1/*
2 * Copyright (C) 2014 Satoshi Noguchi
3 * Copyright (C) 2014 Synaptics Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <alloca.h>
19#include <time.h>
20#include <stdint.h>
21#include <stdio.h>
22#include <unistd.h>
23#include <string.h>
24#include <stdlib.h>
25#include <errno.h>
26#include <math.h>
27
28#include "testutil.h"
29#include "f54test.h"
30#include "rmidevice.h"
31#include "display.h"
32
33/* Most recent device status event */
34#define RMI_F01_STATUS_CODE(status)		((status) & 0x0f)
35/* Indicates that flash programming is enabled (bootloader mode). */
36#define RMI_F01_STATUS_BOOTLOADER(status)	(!!((status) & 0x40))
37
38/*
39 * Sleep mode controls power management on the device and affects all
40 * functions of the device.
41 */
42#define RMI_F01_CTRL0_SLEEP_MODE_MASK	0x03
43
44#define RMI_SLEEP_MODE_NORMAL		0x00
45#define RMI_SLEEP_MODE_SENSOR_SLEEP	0x01
46#define RMI_SLEEP_MODE_RESERVED0	0x02
47#define RMI_SLEEP_MODE_RESERVED1	0x03
48
49/*
50 * This bit disables whatever sleep mode may be selected by the sleep_mode
51 * field and forces the device to run at full power without sleeping.
52 */
53#define RMI_F01_CRTL0_NOSLEEP_BIT	(1 << 2)
54
55F54Test::~F54Test()
56{
57	if (m_txAssignment != NULL) delete [] m_txAssignment;
58	if (m_rxAssignment != NULL) delete [] m_rxAssignment;
59}
60
61int F54Test::Prepare(f54_report_types reportType)
62{
63	int retval;
64	unsigned char data;
65
66	retval = FindTestFunctions();
67	if (retval != TEST_SUCCESS)
68		return retval;
69
70	retval = m_device.QueryBasicProperties();
71	if (retval < 0)
72		return TEST_FAIL_QUERY_BASIC_PROPERTIES;
73
74	retval = ReadF54Queries();
75	if (retval != TEST_SUCCESS)
76		return retval;
77
78	retval = SetupF54Controls();
79	if (retval != TEST_SUCCESS)
80		return retval;
81
82	retval = ReadF55Queries();
83	if (retval != TEST_SUCCESS)
84		return retval;
85
86	retval = SetF54ReportType(reportType);
87	if (retval != TEST_SUCCESS)
88		return retval;
89
90	retval = SetF54Interrupt();
91	if (retval != TEST_SUCCESS)
92		return retval;
93
94	data = (unsigned char)m_reportType;
95	retval = m_device.Write(m_f54.GetDataBase(), &data, 1);
96	if (retval < 0)
97		return retval;
98
99	return TEST_SUCCESS;
100}
101
102int F54Test::Run()
103{
104	int retval;
105	unsigned char command;
106
107	command = (unsigned char)COMMAND_GET_REPORT;
108	retval = DoF54Command(command);
109	if (retval != TEST_SUCCESS)
110		return retval;
111
112	retval = ReadF54Report();
113	if (retval != TEST_SUCCESS)
114		return retval;
115
116	retval = ShowF54Report();
117	if (retval != TEST_SUCCESS)
118		return retval;
119
120	return TEST_SUCCESS;
121}
122
123int F54Test::SetF54ReportType(f54_report_types report_type)
124{
125	switch (report_type) {
126	case F54_8BIT_IMAGE:
127	case F54_16BIT_IMAGE:
128	case F54_RAW_16BIT_IMAGE:
129	case F54_HIGH_RESISTANCE:
130	case F54_TX_TO_TX_SHORTS:
131	case F54_RX_TO_RX_SHORTS_1:
132	case F54_TRUE_BASELINE:
133	case F54_FULL_RAW_CAP_MIN_MAX:
134	case F54_RX_OPENS_1:
135	case F54_TX_OPENS:
136	case F54_TX_TO_GND_SHORTS:
137	case F54_RX_TO_RX_SHORTS_2:
138	case F54_RX_OPENS_2:
139	case F54_FULL_RAW_CAP:
140	case F54_FULL_RAW_CAP_NO_RX_COUPLING:
141	case F54_SENSOR_SPEED:
142	case F54_ADC_RANGE:
143	case F54_TRX_OPENS:
144	case F54_TRX_TO_GND_SHORTS:
145	case F54_TRX_SHORTS:
146	case F54_ABS_RAW_CAP:
147	case F54_ABS_DELTA_CAP:
148		m_reportType = report_type;
149		return SetF54ReportSize(report_type);
150	default:
151		m_reportType = INVALID_REPORT_TYPE;
152		m_reportSize = 0;
153		return TEST_FAIL_INVALID_PARAMETER;
154	}
155}
156
157int F54Test::SetF54ReportSize(f54_report_types report_type)
158{
159	int retval;
160	unsigned char tx = m_txAssigned;
161	unsigned char rx = m_rxAssigned;
162
163	switch (report_type) {
164	case F54_8BIT_IMAGE:
165		m_reportSize = tx * rx;
166		break;
167	case F54_16BIT_IMAGE:
168	case F54_RAW_16BIT_IMAGE:
169	case F54_TRUE_BASELINE:
170	case F54_FULL_RAW_CAP:
171	case F54_FULL_RAW_CAP_NO_RX_COUPLING:
172	case F54_SENSOR_SPEED:
173		m_reportSize = 2 * tx * rx;
174		break;
175	case F54_HIGH_RESISTANCE:
176		m_reportSize = HIGH_RESISTANCE_DATA_SIZE;
177		break;
178	case F54_TX_TO_TX_SHORTS:
179	case F54_TX_OPENS:
180	case F54_TX_TO_GND_SHORTS:
181		m_reportSize = (tx + 7) / 8;
182		break;
183	case F54_RX_TO_RX_SHORTS_1:
184	case F54_RX_OPENS_1:
185		if (rx < tx)
186			m_reportSize = 2 * rx * rx;
187		else
188			m_reportSize = 2 * tx * rx;
189		break;
190	case F54_FULL_RAW_CAP_MIN_MAX:
191		m_reportSize = FULL_RAW_CAP_MIN_MAX_DATA_SIZE;
192		break;
193	case F54_RX_TO_RX_SHORTS_2:
194	case F54_RX_OPENS_2:
195		if (rx <= tx)
196			m_reportSize = 0;
197		else
198			m_reportSize = 2 * rx * (rx - tx);
199		break;
200	case F54_ADC_RANGE:
201		if (m_f54Query.has_signal_clarity) {
202
203			retval = m_device.Read(m_f54Control.reg_41.address,
204					m_f54Control.reg_41.data,
205					sizeof(m_f54Control.reg_41.data));
206			if (retval < 0) {
207				m_reportSize = 0;
208				break;
209			}
210			if (m_f54Control.reg_41.no_signal_clarity) {
211				if (tx % 4)
212					tx += 4 - (tx % 4);
213			}
214		}
215		m_reportSize = 2 * tx * rx;
216		break;
217	case F54_TRX_OPENS:
218	case F54_TRX_TO_GND_SHORTS:
219	case F54_TRX_SHORTS:
220		m_reportSize = TRX_OPEN_SHORT_DATA_SIZE;
221		break;
222	case F54_ABS_RAW_CAP:
223	case F54_ABS_DELTA_CAP:
224		m_reportSize = 4 * (tx + rx);
225		break;
226	default:
227		m_reportSize = 0;
228		return TEST_FAIL_INVALID_PARAMETER;
229	}
230
231	return TEST_SUCCESS;
232}
233
234int F54Test::FindTestFunctions()
235{
236	if (0 > m_device.ScanPDT(0x00, 10))
237		return TEST_FAIL_SCAN_PDT;
238
239	if (!m_device.GetFunction(m_f01, 0x01))
240		return TEST_FAIL_NO_FUNCTION_01;
241
242	if (!m_device.GetFunction(m_f54, 0x54))
243		return TEST_FAIL_NO_FUNCTION_54;
244
245	if (!m_device.GetFunction(m_f55, 0x55))
246		return TEST_FAIL_NO_FUNCTION_55;
247
248	return TEST_SUCCESS;
249}
250
251int F54Test::ReadF54Queries()
252{
253	int retval;
254	unsigned short query_addr = m_f54.GetQueryBase();
255	unsigned char offset;
256
257	retval = m_device.Read(query_addr,
258			       m_f54Query.data,
259			       sizeof(m_f54Query.data));
260	if (retval < 0)
261		return retval;
262
263	offset = sizeof(m_f54Query.data);
264
265	/* query 12 */
266	if (m_f54Query.has_sense_frequency_control == 0)
267		offset -= 1;
268
269	/* query 13 */
270	if (m_f54Query.has_query13) {
271		retval = m_device.Read(query_addr + offset,
272				m_f54Query_13.data,
273				sizeof(m_f54Query_13.data));
274		if (retval < 0)
275			return retval;
276		offset += 1;
277	}
278
279	/* query 14 */
280	if ((m_f54Query.has_query13) && (m_f54Query_13.has_ctrl87))
281		offset += 1;
282
283	/* query 15 */
284	if (m_f54Query.has_query15) {
285		retval = m_device.Read(query_addr + offset,
286				m_f54Query_15.data,
287				sizeof(m_f54Query_15.data));
288		if (retval < 0)
289			return retval;
290		offset += 1;
291	}
292
293	/* query 16 */
294	if ((m_f54Query.has_query15) && (m_f54Query_15.has_query16)) {
295		retval = m_device.Read(query_addr + offset,
296				m_f54Query_16.data,
297				sizeof(m_f54Query_16.data));
298		if (retval < 0)
299			return retval;
300		offset += 1;
301	}
302
303	/* query 17 */
304	if ((m_f54Query.has_query15) &&
305			(m_f54Query_15.has_query16) &&
306			(m_f54Query_16.has_query17))
307		offset += 1;
308
309	/* query 18 */
310	if ((m_f54Query.has_query15) &&
311			(m_f54Query_15.has_query16) &&
312			(m_f54Query_16.has_ctrl94_query18))
313		offset += 1;
314
315	/* query 19 */
316	if ((m_f54Query.has_query15) &&
317			(m_f54Query_15.has_query16) &&
318			(m_f54Query_16.has_ctrl95_query19))
319		offset += 1;
320
321	/* query 20 */
322	if ((m_f54Query.has_query15) && (m_f54Query_15.has_query20))
323		offset += 1;
324
325	/* query 21 */
326	if ((m_f54Query.has_query15) && (m_f54Query_15.has_query21)) {
327		retval = m_device.Read(query_addr + offset,
328				m_f54Query_21.data,
329				sizeof(m_f54Query_21.data));
330		if (retval < 0)
331			return retval;
332		offset += 1;
333	}
334
335	/* query 22 */
336	if ((m_f54Query.has_query15) && (m_f54Query_15.has_query22)) {
337		retval = m_device.Read(query_addr + offset,
338				m_f54Query_22.data,
339				sizeof(m_f54Query_22.data));
340		if (retval < 0)
341			return retval;
342		offset += 1;
343	}
344
345	/* query 23 */
346	if ((m_f54Query.has_query15) &&
347			(m_f54Query_15.has_query22) &&
348			(m_f54Query_22.has_query23)) {
349		retval = m_device.Read(query_addr + offset,
350				m_f54Query_23.data,
351				sizeof(m_f54Query_23.data));
352		if (retval < 0)
353			return retval;
354		offset += 1;
355	}
356
357	/* query 24 */
358	if ((m_f54Query.has_query15) &&
359			(m_f54Query_15.has_query21) &&
360			(m_f54Query_21.has_query24_data18))
361		offset += 1;
362
363	/* query 25 */
364	if ((m_f54Query.has_query15) && (m_f54Query_15.has_query25)) {
365		retval = m_device.Read(query_addr + offset,
366				m_f54Query_25.data,
367				sizeof(m_f54Query_25.data));
368		if (retval < 0)
369			return retval;
370		offset += 1;
371	}
372
373	/* query 26 */
374	if ((m_f54Query.has_query15) &&
375			(m_f54Query_15.has_query22) &&
376			(m_f54Query_22.has_ctrl103_query26))
377		offset += 1;
378
379	/* query 27 */
380	if ((m_f54Query.has_query15) &&
381			(m_f54Query_15.has_query25) &&
382			(m_f54Query_25.has_query27)) {
383		retval = m_device.Read(query_addr + offset,
384				m_f54Query_27.data,
385				sizeof(m_f54Query_27.data));
386		if (retval < 0)
387			return retval;
388		offset += 1;
389	}
390
391	/* query 28 */
392	if ((m_f54Query.has_query15) &&
393			(m_f54Query_15.has_query22) &&
394			(m_f54Query_22.has_query28))
395		offset += 1;
396
397	/* query 29 */
398	if ((m_f54Query.has_query15) &&
399			(m_f54Query_15.has_query25) &&
400			(m_f54Query_25.has_query27) &&
401			(m_f54Query_27.has_query29)) {
402		retval = m_device.Read(query_addr + offset,
403				m_f54Query_29.data,
404				sizeof(m_f54Query_29.data));
405		if (retval < 0)
406			return retval;
407		offset += 1;
408	}
409
410	/* query 30 */
411	if ((m_f54Query.has_query15) &&
412			(m_f54Query_15.has_query25) &&
413			(m_f54Query_25.has_query27) &&
414			(m_f54Query_27.has_query29) &&
415			(m_f54Query_29.has_query30)) {
416		retval = m_device.Read(query_addr + offset,
417				m_f54Query_30.data,
418				sizeof(m_f54Query_30.data));
419		if (retval < 0)
420			return retval;
421		offset += 1;
422	}
423
424	/* query 31 */
425	if ((m_f54Query.has_query15) &&
426			(m_f54Query_15.has_query25) &&
427			(m_f54Query_25.has_query27) &&
428			(m_f54Query_27.has_query29) &&
429			(m_f54Query_29.has_query30) &&
430			(m_f54Query_30.has_ctrl122_query31))
431		offset += 1;
432
433	/* query 32 */
434	if ((m_f54Query.has_query15) &&
435			(m_f54Query_15.has_query25) &&
436			(m_f54Query_25.has_query27) &&
437			(m_f54Query_27.has_query29) &&
438			(m_f54Query_29.has_query30) &&
439			(m_f54Query_30.has_query32)) {
440		retval = m_device.Read(query_addr + offset,
441				m_f54Query_32.data,
442				sizeof(m_f54Query_32.data));
443		if (retval < 0)
444			return retval;
445		offset += 1;
446	}
447
448	/* query 33 */
449	if ((m_f54Query.has_query15) &&
450			(m_f54Query_15.has_query25) &&
451			(m_f54Query_25.has_query27) &&
452			(m_f54Query_27.has_query29) &&
453			(m_f54Query_29.has_query30) &&
454			(m_f54Query_30.has_query32) &&
455			(m_f54Query_32.has_query33)) {
456		retval = m_device.Read(query_addr + offset,
457				m_f54Query_33.data,
458				sizeof(m_f54Query_33.data));
459		if (retval < 0)
460			return retval;
461		offset += 1;
462	}
463
464	/* query 34 */
465	if ((m_f54Query.has_query15) &&
466			(m_f54Query_15.has_query25) &&
467			(m_f54Query_25.has_query27) &&
468			(m_f54Query_27.has_query29) &&
469			(m_f54Query_29.has_query30) &&
470			(m_f54Query_30.has_query32) &&
471			(m_f54Query_32.has_query34))
472		offset += 1;
473
474	/* query 35 */
475	if ((m_f54Query.has_query15) &&
476			(m_f54Query_15.has_query25) &&
477			(m_f54Query_25.has_query27) &&
478			(m_f54Query_27.has_query29) &&
479			(m_f54Query_29.has_query30) &&
480			(m_f54Query_30.has_query32) &&
481			(m_f54Query_32.has_query35)) {
482		retval = m_device.Read(query_addr + offset,
483				m_f54Query_35.data,
484				sizeof(m_f54Query_35.data));
485		if (retval < 0)
486			return retval;
487		offset += 1;
488	}
489
490	/* query 36 */
491	if ((m_f54Query.has_query15) &&
492			(m_f54Query_15.has_query25) &&
493			(m_f54Query_25.has_query27) &&
494			(m_f54Query_27.has_query29) &&
495			(m_f54Query_29.has_query30) &&
496			(m_f54Query_30.has_query32) &&
497			(m_f54Query_32.has_query33) &&
498			(m_f54Query_33.has_query36)) {
499		retval = m_device.Read(query_addr + offset,
500				m_f54Query_36.data,
501				sizeof(m_f54Query_36.data));
502		if (retval < 0)
503			return retval;
504		offset += 1;
505	}
506
507	/* query 37 */
508	if ((m_f54Query.has_query15) &&
509			(m_f54Query_15.has_query25) &&
510			(m_f54Query_25.has_query27) &&
511			(m_f54Query_27.has_query29) &&
512			(m_f54Query_29.has_query30) &&
513			(m_f54Query_30.has_query32) &&
514			(m_f54Query_32.has_query33) &&
515			(m_f54Query_33.has_query36) &&
516			(m_f54Query_36.has_query37))
517		offset += 1;
518
519	/* query 38 */
520	if ((m_f54Query.has_query15) &&
521			(m_f54Query_15.has_query25) &&
522			(m_f54Query_25.has_query27) &&
523			(m_f54Query_27.has_query29) &&
524			(m_f54Query_29.has_query30) &&
525			(m_f54Query_30.has_query32) &&
526			(m_f54Query_32.has_query33) &&
527			(m_f54Query_33.has_query36) &&
528			(m_f54Query_36.has_query38)) {
529		retval = m_device.Read(query_addr + offset,
530				m_f54Query_38.data,
531				sizeof(m_f54Query_38.data));
532		if (retval < 0)
533			return retval;
534		offset += 1;
535	}
536
537	return TEST_SUCCESS;;
538}
539
540int F54Test::SetupF54Controls()
541{
542	unsigned char length;
543	unsigned char num_of_sensing_freqs;
544	unsigned short reg_addr = m_f54.GetControlBase();
545
546	num_of_sensing_freqs = m_f54Query.number_of_sensing_frequencies;
547
548	/* control 0 */
549	reg_addr += CONTROL_0_SIZE;
550
551	/* control 1 */
552	if ((m_f54Query.touch_controller_family == 0) ||
553			(m_f54Query.touch_controller_family == 1))
554		reg_addr += CONTROL_1_SIZE;
555
556	/* control 2 */
557	reg_addr += CONTROL_2_SIZE;
558
559	/* control 3 */
560	if (m_f54Query.has_pixel_touch_threshold_adjustment == 1)
561		reg_addr += CONTROL_3_SIZE;
562
563	/* controls 4 5 6 */
564	if ((m_f54Query.touch_controller_family == 0) ||
565			(m_f54Query.touch_controller_family == 1))
566		reg_addr += CONTROL_4_6_SIZE;
567
568	/* control 7 */
569	if (m_f54Query.touch_controller_family == 1) {
570		m_f54Control.reg_7.address = reg_addr;
571		reg_addr += CONTROL_7_SIZE;
572	}
573
574	/* controls 8 9 */
575	if ((m_f54Query.touch_controller_family == 0) ||
576			(m_f54Query.touch_controller_family == 1))
577		reg_addr += CONTROL_8_9_SIZE;
578
579	/* control 10 */
580	if (m_f54Query.has_interference_metric == 1)
581		reg_addr += CONTROL_10_SIZE;
582
583	/* control 11 */
584	if (m_f54Query.has_ctrl11 == 1)
585		reg_addr += CONTROL_11_SIZE;
586
587	/* controls 12 13 */
588	if (m_f54Query.has_relaxation_control == 1)
589		reg_addr += CONTROL_12_13_SIZE;
590
591	/* controls 14 15 16 */
592	if (m_f54Query.has_sensor_assignment == 1) {
593		reg_addr += CONTROL_14_SIZE;
594		reg_addr += CONTROL_15_SIZE * m_f54Query.num_of_rx_electrodes;
595		reg_addr += CONTROL_16_SIZE * m_f54Query.num_of_tx_electrodes;
596	}
597
598	/* controls 17 18 19 */
599	if (m_f54Query.has_sense_frequency_control == 1) {
600		reg_addr += CONTROL_17_SIZE * num_of_sensing_freqs;
601		reg_addr += CONTROL_18_SIZE * num_of_sensing_freqs;
602		reg_addr += CONTROL_19_SIZE * num_of_sensing_freqs;
603	}
604
605	/* control 20 */
606	reg_addr += CONTROL_20_SIZE;
607
608	/* control 21 */
609	if (m_f54Query.has_sense_frequency_control == 1)
610		reg_addr += CONTROL_21_SIZE;
611
612	/* controls 22 23 24 25 26 */
613	if (m_f54Query.has_firmware_noise_mitigation == 1)
614		reg_addr += CONTROL_22_26_SIZE;
615
616	/* control 27 */
617	if (m_f54Query.has_iir_filter == 1)
618		reg_addr += CONTROL_27_SIZE;
619
620	/* control 28 */
621	if (m_f54Query.has_firmware_noise_mitigation == 1)
622		reg_addr += CONTROL_28_SIZE;
623
624	/* control 29 */
625	if (m_f54Query.has_cmn_removal == 1)
626		reg_addr += CONTROL_29_SIZE;
627
628	/* control 30 */
629	if (m_f54Query.has_cmn_maximum == 1)
630		reg_addr += CONTROL_30_SIZE;
631
632	/* control 31 */
633	if (m_f54Query.has_touch_hysteresis == 1)
634		reg_addr += CONTROL_31_SIZE;
635
636	/* controls 32 33 34 35 */
637	if (m_f54Query.has_edge_compensation == 1)
638		reg_addr += CONTROL_32_35_SIZE;
639
640	/* control 36 */
641	if ((m_f54Query.curve_compensation_mode == 1) ||
642			(m_f54Query.curve_compensation_mode == 2)) {
643		if (m_f54Query.curve_compensation_mode == 1) {
644			length = std::max(m_f54Query.num_of_rx_electrodes,
645					m_f54Query.num_of_tx_electrodes);
646		} else if (m_f54Query.curve_compensation_mode == 2) {
647			length = m_f54Query.num_of_rx_electrodes;
648		}
649		reg_addr += CONTROL_36_SIZE * length;
650	}
651
652	/* control 37 */
653	if (m_f54Query.curve_compensation_mode == 2)
654		reg_addr += CONTROL_37_SIZE * m_f54Query.num_of_tx_electrodes;
655
656	/* controls 38 39 40 */
657	if (m_f54Query.has_per_frequency_noise_control == 1) {
658		reg_addr += CONTROL_38_SIZE * num_of_sensing_freqs;
659		reg_addr += CONTROL_39_SIZE * num_of_sensing_freqs;
660		reg_addr += CONTROL_40_SIZE * num_of_sensing_freqs;
661	}
662
663	/* control 41 */
664	if (m_f54Query.has_signal_clarity == 1) {
665		m_f54Control.reg_41.address = reg_addr;
666		reg_addr += CONTROL_41_SIZE;
667	}
668
669	/* control 42 */
670	if (m_f54Query.has_variance_metric == 1)
671		reg_addr += CONTROL_42_SIZE;
672
673	/* controls 43 44 45 46 47 48 49 50 51 52 53 54 */
674	if (m_f54Query.has_multi_metric_state_machine == 1)
675		reg_addr += CONTROL_43_54_SIZE;
676
677	/* controls 55 56 */
678	if (m_f54Query.has_0d_relaxation_control == 1)
679		reg_addr += CONTROL_55_56_SIZE;
680
681	/* control 57 */
682	if (m_f54Query.has_0d_acquisition_control == 1) {
683		m_f54Control.reg_57.address = reg_addr;
684		reg_addr += CONTROL_57_SIZE;
685	}
686
687	/* control 58 */
688	if (m_f54Query.has_0d_acquisition_control == 1)
689		reg_addr += CONTROL_58_SIZE;
690
691	/* control 59 */
692	if (m_f54Query.has_h_blank == 1)
693		reg_addr += CONTROL_59_SIZE;
694
695	/* controls 60 61 62 */
696	if ((m_f54Query.has_h_blank == 1) ||
697			(m_f54Query.has_v_blank == 1) ||
698			(m_f54Query.has_long_h_blank == 1))
699		reg_addr += CONTROL_60_62_SIZE;
700
701	/* control 63 */
702	if ((m_f54Query.has_h_blank == 1) ||
703			(m_f54Query.has_v_blank == 1) ||
704			(m_f54Query.has_long_h_blank == 1) ||
705			(m_f54Query.has_slew_metric == 1) ||
706			(m_f54Query.has_slew_option == 1) ||
707			(m_f54Query.has_noise_mitigation2 == 1))
708		reg_addr += CONTROL_63_SIZE;
709
710	/* controls 64 65 66 67 */
711	if (m_f54Query.has_h_blank == 1)
712		reg_addr += CONTROL_64_67_SIZE * 7;
713	else if ((m_f54Query.has_v_blank == 1) ||
714			(m_f54Query.has_long_h_blank == 1))
715		reg_addr += CONTROL_64_67_SIZE;
716
717	/* controls 68 69 70 71 72 73 */
718	if ((m_f54Query.has_h_blank == 1) ||
719			(m_f54Query.has_v_blank == 1) ||
720			(m_f54Query.has_long_h_blank == 1))
721		reg_addr += CONTROL_68_73_SIZE;
722
723	/* control 74 */
724	if (m_f54Query.has_slew_metric == 1)
725		reg_addr += CONTROL_74_SIZE;
726
727	/* control 75 */
728	if (m_f54Query.has_enhanced_stretch == 1)
729		reg_addr += CONTROL_75_SIZE * num_of_sensing_freqs;
730
731	/* control 76 */
732	if (m_f54Query.has_startup_fast_relaxation == 1)
733		reg_addr += CONTROL_76_SIZE;
734
735	/* controls 77 78 */
736	if (m_f54Query.has_esd_control == 1)
737		reg_addr += CONTROL_77_78_SIZE;
738
739	/* controls 79 80 81 82 83 */
740	if (m_f54Query.has_noise_mitigation2 == 1)
741		reg_addr += CONTROL_79_83_SIZE;
742
743	/* controls 84 85 */
744	if (m_f54Query.has_energy_ratio_relaxation == 1)
745		reg_addr += CONTROL_84_85_SIZE;
746
747	/* control 86 */
748	if ((m_f54Query.has_query13 == 1) && (m_f54Query_13.has_ctrl86 == 1))
749		reg_addr += CONTROL_86_SIZE;
750
751	/* control 87 */
752	if ((m_f54Query.has_query13 == 1) && (m_f54Query_13.has_ctrl87 == 1))
753		reg_addr += CONTROL_87_SIZE;
754
755	/* control 88 */
756	if (m_f54Query.has_ctrl88 == 1) {
757		m_f54Control.reg_88.address = reg_addr;
758		reg_addr += CONTROL_88_SIZE;
759	}
760
761	/* control 89 */
762	if ((m_f54Query.has_query13 == 1) &&
763			(m_f54Query_13.has_cidim == 1 ||
764			m_f54Query_13.has_noise_mitigation_enhancement ||
765			m_f54Query_13.has_rail_im))
766		reg_addr += CONTROL_89_SIZE;
767
768	/* control 90 */
769	if ((m_f54Query.has_query15) && (m_f54Query_15.has_ctrl90))
770		reg_addr += CONTROL_90_SIZE;
771
772	/* control 91 */
773	if ((m_f54Query.has_query15) &&
774			(m_f54Query_15.has_query21) &&
775			(m_f54Query_21.has_ctrl91))
776		reg_addr += CONTROL_91_SIZE;
777
778	/* control 92 */
779	if ((m_f54Query.has_query15) &&
780			(m_f54Query_15.has_query16) &&
781			(m_f54Query_16.has_ctrl92))
782		reg_addr += CONTROL_92_SIZE;
783
784	/* control 93 */
785	if ((m_f54Query.has_query15) &&
786			(m_f54Query_15.has_query16) &&
787			(m_f54Query_16.has_ctrl93))
788		reg_addr += CONTROL_93_SIZE;
789
790	/* control 94 */
791	if ((m_f54Query.has_query15) &&
792			(m_f54Query_15.has_query16) &&
793			(m_f54Query_16.has_ctrl94_query18))
794		reg_addr += CONTROL_94_SIZE;
795
796	/* control 95 */
797	if ((m_f54Query.has_query15) &&
798			(m_f54Query_15.has_query16) &&
799			(m_f54Query_16.has_ctrl95_query19))
800		reg_addr += CONTROL_95_SIZE;
801
802	/* control 96 */
803	if ((m_f54Query.has_query15) &&
804			(m_f54Query_15.has_query21) &&
805			(m_f54Query_21.has_ctrl96))
806		reg_addr += CONTROL_96_SIZE;
807
808	/* control 97 */
809	if ((m_f54Query.has_query15) &&
810			(m_f54Query_15.has_query21) &&
811			(m_f54Query_21.has_ctrl97))
812		reg_addr += CONTROL_97_SIZE;
813
814	/* control 98 */
815	if ((m_f54Query.has_query15) &&
816			(m_f54Query_15.has_query21) &&
817			(m_f54Query_21.has_ctrl98))
818		reg_addr += CONTROL_98_SIZE;
819
820	/* control 99 */
821	if (m_f54Query.touch_controller_family == 2)
822		reg_addr += CONTROL_99_SIZE;
823
824	/* control 100 */
825	if ((m_f54Query.has_query15) &&
826			(m_f54Query_15.has_query16) &&
827			(m_f54Query_16.has_ctrl100))
828		reg_addr += CONTROL_100_SIZE;
829
830	/* control 101 */
831	if ((m_f54Query.has_query15) &&
832			(m_f54Query_15.has_query22) &&
833			(m_f54Query_22.has_ctrl101))
834		reg_addr += CONTROL_101_SIZE;
835
836
837	/* control 102 */
838	if ((m_f54Query.has_query15) &&
839			(m_f54Query_15.has_query22) &&
840			(m_f54Query_22.has_query23) &&
841			(m_f54Query_23.has_ctrl102))
842		reg_addr += CONTROL_102_SIZE;
843
844	/* control 103 */
845	if ((m_f54Query.has_query15) &&
846			(m_f54Query_15.has_query22) &&
847			(m_f54Query_22.has_ctrl103_query26))
848		reg_addr += CONTROL_103_SIZE;
849
850	/* control 104 */
851	if ((m_f54Query.has_query15) &&
852			(m_f54Query_15.has_query22) &&
853			(m_f54Query_22.has_ctrl104))
854		reg_addr += CONTROL_104_SIZE;
855
856	/* control 105 */
857	if ((m_f54Query.has_query15) &&
858			(m_f54Query_15.has_query22) &&
859			(m_f54Query_22.has_ctrl105))
860		reg_addr += CONTROL_105_SIZE;
861
862	/* control 106 */
863	if ((m_f54Query.has_query15) &&
864			(m_f54Query_15.has_query25) &&
865			(m_f54Query_25.has_ctrl106))
866		reg_addr += CONTROL_106_SIZE;
867
868	/* control 107 */
869	if ((m_f54Query.has_query15) &&
870			(m_f54Query_15.has_query25) &&
871			(m_f54Query_25.has_ctrl107))
872		reg_addr += CONTROL_107_SIZE;
873
874	/* control 108 */
875	if ((m_f54Query.has_query15) &&
876			(m_f54Query_15.has_query25) &&
877			(m_f54Query_25.has_ctrl108))
878		reg_addr += CONTROL_108_SIZE;
879
880	/* control 109 */
881	if ((m_f54Query.has_query15) &&
882			(m_f54Query_15.has_query25) &&
883			(m_f54Query_25.has_ctrl109))
884		reg_addr += CONTROL_109_SIZE;
885
886	/* control 110 */
887	if ((m_f54Query.has_query15) &&
888			(m_f54Query_15.has_query25) &&
889			(m_f54Query_25.has_query27) &&
890			(m_f54Query_27.has_ctrl110)) {
891		m_f54Control.reg_110.address = reg_addr;
892		reg_addr += CONTROL_110_SIZE;
893	}
894
895	/* control 111 */
896	if ((m_f54Query.has_query15) &&
897			(m_f54Query_15.has_query25) &&
898			(m_f54Query_25.has_query27) &&
899			(m_f54Query_27.has_ctrl111))
900		reg_addr += CONTROL_111_SIZE;
901
902	/* control 112 */
903	if ((m_f54Query.has_query15) &&
904			(m_f54Query_15.has_query25) &&
905			(m_f54Query_25.has_query27) &&
906			(m_f54Query_27.has_ctrl112))
907		reg_addr += CONTROL_112_SIZE;
908
909	/* control 113 */
910	if ((m_f54Query.has_query15) &&
911			(m_f54Query_15.has_query25) &&
912			(m_f54Query_25.has_query27) &&
913			(m_f54Query_27.has_ctrl113))
914		reg_addr += CONTROL_113_SIZE;
915
916	/* control 114 */
917	if ((m_f54Query.has_query15) &&
918			(m_f54Query_15.has_query25) &&
919			(m_f54Query_25.has_query27) &&
920			(m_f54Query_27.has_ctrl114))
921		reg_addr += CONTROL_114_SIZE;
922
923	/* control 115 */
924	if ((m_f54Query.has_query15) &&
925			(m_f54Query_15.has_query25) &&
926			(m_f54Query_25.has_query27) &&
927			(m_f54Query_27.has_query29) &&
928			(m_f54Query_29.has_ctrl115))
929		reg_addr += CONTROL_115_SIZE;
930
931	/* control 116 */
932	if ((m_f54Query.has_query15) &&
933			(m_f54Query_15.has_query25) &&
934			(m_f54Query_25.has_query27) &&
935			(m_f54Query_27.has_query29) &&
936			(m_f54Query_29.has_ctrl116))
937		reg_addr += CONTROL_116_SIZE;
938
939	/* control 117 */
940	if ((m_f54Query.has_query15) &&
941			(m_f54Query_15.has_query25) &&
942			(m_f54Query_25.has_query27) &&
943			(m_f54Query_27.has_query29) &&
944			(m_f54Query_29.has_ctrl117))
945		reg_addr += CONTROL_117_SIZE;
946
947	/* control 118 */
948	if ((m_f54Query.has_query15) &&
949			(m_f54Query_15.has_query25) &&
950			(m_f54Query_25.has_query27) &&
951			(m_f54Query_27.has_query29) &&
952			(m_f54Query_29.has_query30) &&
953			(m_f54Query_30.has_ctrl118))
954		reg_addr += CONTROL_118_SIZE;
955
956	/* control 119 */
957	if ((m_f54Query.has_query15) &&
958			(m_f54Query_15.has_query25) &&
959			(m_f54Query_25.has_query27) &&
960			(m_f54Query_27.has_query29) &&
961			(m_f54Query_29.has_query30) &&
962			(m_f54Query_30.has_ctrl119))
963		reg_addr += CONTROL_119_SIZE;
964
965	/* control 120 */
966	if ((m_f54Query.has_query15) &&
967			(m_f54Query_15.has_query25) &&
968			(m_f54Query_25.has_query27) &&
969			(m_f54Query_27.has_query29) &&
970			(m_f54Query_29.has_query30) &&
971			(m_f54Query_30.has_ctrl120))
972		reg_addr += CONTROL_120_SIZE;
973
974	/* control 121 */
975	if ((m_f54Query.has_query15) &&
976			(m_f54Query_15.has_query25) &&
977			(m_f54Query_25.has_query27) &&
978			(m_f54Query_27.has_query29) &&
979			(m_f54Query_29.has_query30) &&
980			(m_f54Query_30.has_ctrl121))
981		reg_addr += CONTROL_121_SIZE;
982
983	/* control 122 */
984	if ((m_f54Query.has_query15) &&
985			(m_f54Query_15.has_query25) &&
986			(m_f54Query_25.has_query27) &&
987			(m_f54Query_27.has_query29) &&
988			(m_f54Query_29.has_query30) &&
989			(m_f54Query_30.has_ctrl122_query31))
990		reg_addr += CONTROL_122_SIZE;
991
992	/* control 123 */
993	if ((m_f54Query.has_query15) &&
994			(m_f54Query_15.has_query25) &&
995			(m_f54Query_25.has_query27) &&
996			(m_f54Query_27.has_query29) &&
997			(m_f54Query_29.has_query30) &&
998			(m_f54Query_30.has_ctrl123))
999		reg_addr += CONTROL_123_SIZE;
1000
1001	/* control 124 reserved */
1002
1003	/* control 125 */
1004	if ((m_f54Query.has_query15) &&
1005			(m_f54Query_15.has_query25) &&
1006			(m_f54Query_25.has_query27) &&
1007			(m_f54Query_27.has_query29) &&
1008			(m_f54Query_29.has_query30) &&
1009			(m_f54Query_30.has_query32) &&
1010			(m_f54Query_32.has_ctrl125))
1011		reg_addr += CONTROL_125_SIZE;
1012
1013	/* control 126 */
1014	if ((m_f54Query.has_query15) &&
1015			(m_f54Query_15.has_query25) &&
1016			(m_f54Query_25.has_query27) &&
1017			(m_f54Query_27.has_query29) &&
1018			(m_f54Query_29.has_query30) &&
1019			(m_f54Query_30.has_query32) &&
1020			(m_f54Query_32.has_ctrl126))
1021		reg_addr += CONTROL_126_SIZE;
1022
1023	/* control 127 */
1024	if ((m_f54Query.has_query15) &&
1025			(m_f54Query_15.has_query25) &&
1026			(m_f54Query_25.has_query27) &&
1027			(m_f54Query_27.has_query29) &&
1028			(m_f54Query_29.has_query30) &&
1029			(m_f54Query_30.has_query32) &&
1030			(m_f54Query_32.has_ctrl127))
1031		reg_addr += CONTROL_127_SIZE;
1032
1033	/* controls 128 129 130 131 reserved */
1034
1035	/* control 132 */
1036	if ((m_f54Query.has_query15) &&
1037			(m_f54Query_15.has_query25) &&
1038			(m_f54Query_25.has_query27) &&
1039			(m_f54Query_27.has_query29) &&
1040			(m_f54Query_29.has_query30) &&
1041			(m_f54Query_30.has_query32) &&
1042			(m_f54Query_32.has_query33) &&
1043			(m_f54Query_33.has_ctrl132))
1044		reg_addr += CONTROL_132_SIZE;
1045
1046	/* control 133 */
1047	if ((m_f54Query.has_query15) &&
1048			(m_f54Query_15.has_query25) &&
1049			(m_f54Query_25.has_query27) &&
1050			(m_f54Query_27.has_query29) &&
1051			(m_f54Query_29.has_query30) &&
1052			(m_f54Query_30.has_query32) &&
1053			(m_f54Query_32.has_query33) &&
1054			(m_f54Query_33.has_ctrl133))
1055		reg_addr += CONTROL_133_SIZE;
1056
1057	/* control 134 */
1058	if ((m_f54Query.has_query15) &&
1059			(m_f54Query_15.has_query25) &&
1060			(m_f54Query_25.has_query27) &&
1061			(m_f54Query_27.has_query29) &&
1062			(m_f54Query_29.has_query30) &&
1063			(m_f54Query_30.has_query32) &&
1064			(m_f54Query_32.has_query33) &&
1065			(m_f54Query_33.has_ctrl134))
1066		reg_addr += CONTROL_134_SIZE;
1067
1068	/* controls 135 136 reserved */
1069
1070	/* control 137 */
1071	if ((m_f54Query.has_query15) &&
1072			(m_f54Query_15.has_query25) &&
1073			(m_f54Query_25.has_query27) &&
1074			(m_f54Query_27.has_query29) &&
1075			(m_f54Query_29.has_query30) &&
1076			(m_f54Query_30.has_query32) &&
1077			(m_f54Query_32.has_query35) &&
1078			(m_f54Query_35.has_ctrl137))
1079		reg_addr += CONTROL_137_SIZE;
1080
1081	/* control 138 */
1082	if ((m_f54Query.has_query15) &&
1083			(m_f54Query_15.has_query25) &&
1084			(m_f54Query_25.has_query27) &&
1085			(m_f54Query_27.has_query29) &&
1086			(m_f54Query_29.has_query30) &&
1087			(m_f54Query_30.has_query32) &&
1088			(m_f54Query_32.has_query35) &&
1089			(m_f54Query_35.has_ctrl138))
1090		reg_addr += CONTROL_138_SIZE;
1091
1092	/* control 139 */
1093	if ((m_f54Query.has_query15) &&
1094			(m_f54Query_15.has_query25) &&
1095			(m_f54Query_25.has_query27) &&
1096			(m_f54Query_27.has_query29) &&
1097			(m_f54Query_29.has_query30) &&
1098			(m_f54Query_30.has_query32) &&
1099			(m_f54Query_32.has_query35) &&
1100			(m_f54Query_35.has_ctrl139))
1101		reg_addr += CONTROL_139_SIZE;
1102
1103	/* control 140 */
1104	if ((m_f54Query.has_query15) &&
1105			(m_f54Query_15.has_query25) &&
1106			(m_f54Query_25.has_query27) &&
1107			(m_f54Query_27.has_query29) &&
1108			(m_f54Query_29.has_query30) &&
1109			(m_f54Query_30.has_query32) &&
1110			(m_f54Query_32.has_query35) &&
1111			(m_f54Query_35.has_ctrl140))
1112		reg_addr += CONTROL_140_SIZE;
1113
1114	/* control 141 reserved */
1115
1116	/* control 142 */
1117	if ((m_f54Query.has_query15) &&
1118			(m_f54Query_15.has_query25) &&
1119			(m_f54Query_25.has_query27) &&
1120			(m_f54Query_27.has_query29) &&
1121			(m_f54Query_29.has_query30) &&
1122			(m_f54Query_30.has_query32) &&
1123			(m_f54Query_32.has_query33) &&
1124			(m_f54Query_33.has_query36) &&
1125			(m_f54Query_36.has_ctrl142))
1126		reg_addr += CONTROL_142_SIZE;
1127
1128	/* control 143 */
1129	if ((m_f54Query.has_query15) &&
1130			(m_f54Query_15.has_query25) &&
1131			(m_f54Query_25.has_query27) &&
1132			(m_f54Query_27.has_query29) &&
1133			(m_f54Query_29.has_query30) &&
1134			(m_f54Query_30.has_query32) &&
1135			(m_f54Query_32.has_query33) &&
1136			(m_f54Query_33.has_query36) &&
1137			(m_f54Query_36.has_ctrl143))
1138		reg_addr += CONTROL_143_SIZE;
1139
1140	/* control 144 */
1141	if ((m_f54Query.has_query15) &&
1142			(m_f54Query_15.has_query25) &&
1143			(m_f54Query_25.has_query27) &&
1144			(m_f54Query_27.has_query29) &&
1145			(m_f54Query_29.has_query30) &&
1146			(m_f54Query_30.has_query32) &&
1147			(m_f54Query_32.has_query33) &&
1148			(m_f54Query_33.has_query36) &&
1149			(m_f54Query_36.has_ctrl144))
1150		reg_addr += CONTROL_144_SIZE;
1151
1152	/* control 145 */
1153	if ((m_f54Query.has_query15) &&
1154			(m_f54Query_15.has_query25) &&
1155			(m_f54Query_25.has_query27) &&
1156			(m_f54Query_27.has_query29) &&
1157			(m_f54Query_29.has_query30) &&
1158			(m_f54Query_30.has_query32) &&
1159			(m_f54Query_32.has_query33) &&
1160			(m_f54Query_33.has_query36) &&
1161			(m_f54Query_36.has_ctrl145))
1162		reg_addr += CONTROL_145_SIZE;
1163
1164	/* control 146 */
1165	if ((m_f54Query.has_query15) &&
1166			(m_f54Query_15.has_query25) &&
1167			(m_f54Query_25.has_query27) &&
1168			(m_f54Query_27.has_query29) &&
1169			(m_f54Query_29.has_query30) &&
1170			(m_f54Query_30.has_query32) &&
1171			(m_f54Query_32.has_query33) &&
1172			(m_f54Query_33.has_query36) &&
1173			(m_f54Query_36.has_ctrl146))
1174		reg_addr += CONTROL_146_SIZE;
1175
1176	/* control 147 */
1177	if ((m_f54Query.has_query15) &&
1178			(m_f54Query_15.has_query25) &&
1179			(m_f54Query_25.has_query27) &&
1180			(m_f54Query_27.has_query29) &&
1181			(m_f54Query_29.has_query30) &&
1182			(m_f54Query_30.has_query32) &&
1183			(m_f54Query_32.has_query33) &&
1184			(m_f54Query_33.has_query36) &&
1185			(m_f54Query_36.has_query38) &&
1186			(m_f54Query_38.has_ctrl147))
1187		reg_addr += CONTROL_147_SIZE;
1188
1189	/* control 148 */
1190	if ((m_f54Query.has_query15) &&
1191			(m_f54Query_15.has_query25) &&
1192			(m_f54Query_25.has_query27) &&
1193			(m_f54Query_27.has_query29) &&
1194			(m_f54Query_29.has_query30) &&
1195			(m_f54Query_30.has_query32) &&
1196			(m_f54Query_32.has_query33) &&
1197			(m_f54Query_33.has_query36) &&
1198			(m_f54Query_36.has_query38) &&
1199			(m_f54Query_38.has_ctrl148))
1200		reg_addr += CONTROL_148_SIZE;
1201
1202	/* control 149 */
1203	if ((m_f54Query.has_query15) &&
1204			(m_f54Query_15.has_query25) &&
1205			(m_f54Query_25.has_query27) &&
1206			(m_f54Query_27.has_query29) &&
1207			(m_f54Query_29.has_query30) &&
1208			(m_f54Query_30.has_query32) &&
1209			(m_f54Query_32.has_query33) &&
1210			(m_f54Query_33.has_query36) &&
1211			(m_f54Query_36.has_query38) &&
1212			(m_f54Query_38.has_ctrl149)) {
1213		m_f54Control.reg_149.address = reg_addr;
1214		reg_addr += CONTROL_149_SIZE;
1215	}
1216
1217	return TEST_SUCCESS;
1218}
1219
1220int F54Test::ReadF55Queries()
1221{
1222	int retval;
1223	unsigned char ii;
1224	unsigned char rx_electrodes = m_f54Query.num_of_rx_electrodes;
1225	unsigned char tx_electrodes = m_f54Query.num_of_tx_electrodes;
1226
1227	retval = m_device.Read(m_f55.GetQueryBase(),
1228			m_f55Query.data,
1229			sizeof(m_f55Query.data));
1230	if (retval < 0) {
1231		return retval;
1232	}
1233
1234	if (!m_f55Query.has_sensor_assignment)
1235	{
1236		m_txAssigned = tx_electrodes;
1237		m_rxAssigned = rx_electrodes;
1238		m_txAssignment = NULL;
1239		m_rxAssignment = NULL;
1240		return TEST_SUCCESS;
1241	}
1242
1243	if (m_txAssignment != NULL) delete [] m_txAssignment;
1244	if (m_rxAssignment != NULL) delete [] m_rxAssignment;
1245	m_txAssignment = new unsigned char[tx_electrodes];
1246	m_rxAssignment = new unsigned char[rx_electrodes];
1247
1248	retval = m_device.Read(m_f55.GetControlBase() + SENSOR_TX_MAPPING_OFFSET,
1249			m_txAssignment,
1250			tx_electrodes);
1251	if (retval < 0) {
1252		goto exit;
1253	}
1254
1255	retval = m_device.Read(m_f55.GetControlBase() + SENSOR_RX_MAPPING_OFFSET,
1256			m_rxAssignment,
1257			rx_electrodes);
1258	if (retval < 0) {
1259		goto exit;
1260	}
1261
1262	m_txAssigned = 0;
1263	for (ii = 0; ii < tx_electrodes; ii++) {
1264		if (m_txAssignment[ii] != 0xff)
1265			m_txAssigned++;
1266	}
1267
1268	m_rxAssigned = 0;
1269	for (ii = 0; ii < rx_electrodes; ii++) {
1270		if (m_rxAssignment[ii] != 0xff)
1271			m_rxAssigned++;
1272	}
1273
1274	return TEST_SUCCESS;
1275
1276exit:
1277	if (m_txAssignment != NULL)
1278	{
1279		delete [] m_txAssignment;
1280		m_txAssignment = NULL;
1281	}
1282	if (m_rxAssignment != NULL)
1283	{
1284		delete [] m_rxAssignment;
1285		m_rxAssignment = NULL;
1286	}
1287
1288	return retval;
1289}
1290
1291int F54Test::SetF54Interrupt()
1292{
1293	int retval;
1294	unsigned char mask = m_f54.GetInterruptMask();
1295	unsigned char zero = 0;
1296	unsigned int i;
1297
1298	for (i = 0; i < m_device.GetNumInterruptRegs(); i++)
1299	{
1300		if (i == m_f54.GetInterruptRegNum())
1301		{
1302			retval = m_device.Write(m_f54.GetControlBase() + 1 + i, &mask, 1);
1303		}
1304		else
1305		{
1306			retval = m_device.Write(m_f54.GetControlBase() + 1 + i, &zero, 1);
1307		}
1308
1309		if (retval < 0)
1310			return retval;
1311	}
1312	return TEST_SUCCESS;
1313}
1314
1315int F54Test::DoF54Command(unsigned char command)
1316{
1317	int retval;
1318
1319	retval = m_device.Write(m_f54.GetCommandBase(), &command, 1);
1320	if (retval < 0)
1321		return retval;
1322
1323	retval = WaitForF54CommandCompletion();
1324	if (retval != TEST_SUCCESS)
1325		return retval;
1326
1327	return TEST_SUCCESS;
1328}
1329
1330int F54Test::WaitForF54CommandCompletion()
1331{
1332	int retval;
1333	unsigned char value;
1334	unsigned char timeout_count;
1335
1336	timeout_count = 0;
1337	do {
1338		retval = m_device.Read(m_f54.GetCommandBase(),
1339				&value,
1340				sizeof(value));
1341		if (retval < 0)
1342			return retval;
1343
1344		if (value == 0x00)
1345			break;
1346
1347		Sleep(100);
1348		timeout_count++;
1349	} while (timeout_count < COMMAND_TIMEOUT_100MS);
1350
1351	if (timeout_count == COMMAND_TIMEOUT_100MS) {
1352		return -ETIMEDOUT;
1353	}
1354
1355	return TEST_SUCCESS;
1356}
1357
1358int F54Test::ReadF54Report()
1359{
1360	int retval;
1361	unsigned char report_index[2];
1362
1363	if (m_reportBufferSize < m_reportSize) {
1364		if (m_reportData != NULL)
1365			delete [] m_reportData;
1366		m_reportData = new unsigned char[m_reportSize];
1367		if (!m_reportData) {
1368			m_reportBufferSize = 0;
1369			retval = TEST_FAIL_MEMORY_ALLOCATION;
1370			goto exit;
1371		}
1372		m_reportBufferSize = m_reportSize;
1373	}
1374
1375	report_index[0] = 0;
1376	report_index[1] = 0;
1377
1378	retval = m_device.Write(m_f54.GetDataBase() + REPORT_INDEX_OFFSET,
1379				report_index,
1380				sizeof(report_index));
1381
1382	if (retval < 0)
1383		goto exit;
1384
1385	retval = m_device.Read(m_f54.GetDataBase() + REPORT_DATA_OFFSET,
1386				m_reportData,
1387				m_reportSize);
1388	if (retval < 0)
1389		goto exit;
1390
1391	return TEST_SUCCESS;
1392
1393exit:
1394	if (m_reportData != NULL)
1395	{
1396		delete [] m_reportData;
1397		m_reportData = NULL;
1398	}
1399
1400	return retval;
1401}
1402
1403int F54Test::ShowF54Report()
1404{
1405	unsigned int ii;
1406	unsigned int jj;
1407	unsigned int tx_num = m_txAssigned;
1408	unsigned int rx_num = m_rxAssigned;
1409	char *report_data_8;
1410	short *report_data_16;
1411	int *report_data_32;
1412	unsigned int *report_data_u32;
1413	char buf[256];
1414
1415	switch (m_reportType) {
1416	case F54_8BIT_IMAGE:
1417		report_data_8 = (char *)m_reportData;
1418		for (ii = 0; ii < m_reportSize; ii++) {
1419			sprintf(buf, "%03d: %d\n",
1420					ii, *report_data_8);
1421			m_display.Output(buf);
1422			report_data_8++;
1423		}
1424		break;
1425	case F54_16BIT_IMAGE:
1426	case F54_RAW_16BIT_IMAGE:
1427	case F54_TRUE_BASELINE:
1428	case F54_FULL_RAW_CAP:
1429	case F54_FULL_RAW_CAP_NO_RX_COUPLING:
1430	case F54_SENSOR_SPEED:
1431		report_data_16 = (short *)m_reportData;
1432		sprintf(buf, "tx = %d\nrx = %d\n",
1433				tx_num, rx_num);
1434		m_display.Output(buf);
1435
1436		for (ii = 0; ii < tx_num; ii++) {
1437			for (jj = 0; jj < (rx_num - 1); jj++) {
1438				sprintf(buf, "%-4d ",
1439						*report_data_16);
1440				report_data_16++;
1441				m_display.Output(buf);
1442			}
1443			sprintf(buf, "%-4d\n",
1444					*report_data_16);
1445			m_display.Output(buf);
1446			report_data_16++;
1447		}
1448		break;
1449	case F54_HIGH_RESISTANCE:
1450	case F54_FULL_RAW_CAP_MIN_MAX:
1451		report_data_16 = (short *)m_reportData;
1452		for (ii = 0; ii < m_reportSize; ii += 2) {
1453			sprintf(buf, "%03d: %d\n",
1454					ii / 2, *report_data_16);
1455			m_display.Output(buf);
1456			report_data_16++;
1457		}
1458		break;
1459	case F54_ABS_RAW_CAP:
1460		report_data_u32 = (unsigned int *)m_reportData;
1461		sprintf(buf, "rx ");
1462		m_display.Output(buf);
1463
1464		for (ii = 0; ii < rx_num; ii++) {
1465			sprintf(buf, "     %2d", ii);
1466			m_display.Output(buf);
1467		}
1468		sprintf(buf, "\n");
1469		m_display.Output(buf);
1470
1471		sprintf(buf, "   ");
1472		m_display.Output(buf);
1473
1474		for (ii = 0; ii < rx_num; ii++) {
1475			sprintf(buf, "  %5u",
1476					*report_data_u32);
1477			report_data_u32++;
1478			m_display.Output(buf);
1479		}
1480		sprintf(buf, "\n");
1481		m_display.Output(buf);
1482
1483		sprintf(buf, "tx ");
1484		m_display.Output(buf);
1485
1486		for (ii = 0; ii < tx_num; ii++) {
1487			sprintf(buf, "     %2d", ii);
1488			m_display.Output(buf);
1489		}
1490		sprintf(buf, "\n");
1491		m_display.Output(buf);
1492
1493		sprintf(buf, "   ");
1494		m_display.Output(buf);
1495
1496		for (ii = 0; ii < tx_num; ii++) {
1497			sprintf(buf, "  %5u",
1498					*report_data_u32);
1499			report_data_u32++;
1500			m_display.Output(buf);
1501		}
1502		sprintf(buf, "\n");
1503		m_display.Output(buf);
1504
1505		break;
1506	case F54_ABS_DELTA_CAP:
1507		report_data_32 = (int *)m_reportData;
1508		sprintf(buf, "rx ");
1509		m_display.Output(buf);
1510
1511		for (ii = 0; ii < rx_num; ii++) {
1512			sprintf(buf, "     %2d", ii);
1513			m_display.Output(buf);
1514		}
1515		sprintf(buf, "\n");
1516		m_display.Output(buf);
1517
1518		sprintf(buf, "   ");
1519		m_display.Output(buf);
1520
1521		for (ii = 0; ii < rx_num; ii++) {
1522			sprintf(buf, "  %5d",
1523					*report_data_32);
1524			report_data_32++;
1525			m_display.Output(buf);
1526		}
1527		sprintf(buf, "\n");
1528		m_display.Output(buf);
1529
1530		sprintf(buf, "tx ");
1531		m_display.Output(buf);
1532
1533		for (ii = 0; ii < tx_num; ii++) {
1534			sprintf(buf, "     %2d", ii);
1535			m_display.Output(buf);
1536		}
1537		sprintf(buf, "\n");
1538		m_display.Output(buf);
1539
1540		sprintf(buf, "   ");
1541		m_display.Output(buf);
1542
1543		for (ii = 0; ii < tx_num; ii++) {
1544			sprintf(buf, "  %5d",
1545					*report_data_32);
1546			report_data_32++;
1547			m_display.Output(buf);
1548		}
1549		sprintf(buf, "\n");
1550		m_display.Output(buf);
1551
1552		break;
1553	default:
1554		for (ii = 0; ii < m_reportSize; ii++) {
1555			sprintf(buf, "%03d: 0x%02x\n",
1556					ii, m_reportData[ii]);
1557			m_display.Output(buf);
1558		}
1559		break;
1560	}
1561
1562	sprintf(buf, "\n");
1563	m_display.Output(buf);
1564
1565	m_display.Reflesh();
1566
1567	return TEST_SUCCESS;
1568}
1569