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 
~F54Test()55 F54Test::~F54Test()
56 {
57 	if (m_txAssignment != NULL) delete [] m_txAssignment;
58 	if (m_rxAssignment != NULL) delete [] m_rxAssignment;
59 }
60 
Prepare(f54_report_types reportType)61 int 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 
Run()102 int 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 
SetF54ReportType(f54_report_types report_type)123 int 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 
SetF54ReportSize(f54_report_types report_type)157 int 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 
FindTestFunctions()234 int 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 
ReadF54Queries()251 int 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 
SetupF54Controls()540 int 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 
ReadF55Queries()1220 int 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 
1276 exit:
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 
SetF54Interrupt()1291 int 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 
DoF54Command(unsigned char command)1315 int 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 
WaitForF54CommandCompletion()1330 int 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 
ReadF54Report()1358 int 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 
1393 exit:
1394 	if (m_reportData != NULL)
1395 	{
1396 		delete [] m_reportData;
1397 		m_reportData = NULL;
1398 	}
1399 
1400 	return retval;
1401 }
1402 
ShowF54Report()1403 int 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