1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/* SPDX-License-Identifier: GPL-2.0-only */
#include <libpayload.h>
/* Include source to gain access to private defines */
#include "../drivers/speaker.c"
#include <tests/test.h>
void outb(unsigned char val, int port)
{
check_expected(val);
check_expected(port);
}
unsigned char inb(int port)
{
check_expected(port);
return mock_type(unsigned char);
}
static void setup_speaker_enable_calls(u16 freq, u8 port_val)
{
/* Minimal correct value should be at leaset 256. For values lowe than that,
counter will have an incorrect value. Regardless, there is */
u16 reg16 = 1193180 / freq;
/* Select counter 2 */
expect_value(outb, val, 0xb6);
expect_value(outb, port, I82C54_CONTROL_WORD_REGISTER);
/* Write freq. [LSB, MSB] */
expect_value(outb, val, (u8)(reg16 & 0xff));
expect_value(outb, port, I82C54_COUNTER2);
expect_value(outb, val, (u8)(reg16 >> 8));
expect_value(outb, port, I82C54_COUNTER2);
/* Enable PC speaker */
expect_value(inb, port, PC_SPEAKER_PORT);
will_return(inb, port_val);
expect_value(outb, val, port_val | 0x3);
expect_value(outb, port, PC_SPEAKER_PORT);
}
static void test_speaker_enable(void **state)
{
setup_speaker_enable_calls(1, 0);
speaker_enable(1);
setup_speaker_enable_calls(1, 0xff);
speaker_enable(1);
setup_speaker_enable_calls(1, 123);
speaker_enable(1);
setup_speaker_enable_calls(1, -1);
speaker_enable(1);
setup_speaker_enable_calls(-1, 0);
speaker_enable(-1);
setup_speaker_enable_calls(-1, 0xff);
speaker_enable(-1);
setup_speaker_enable_calls(-1, 222);
speaker_enable(-1);
setup_speaker_enable_calls(-1, -1);
speaker_enable(-1);
setup_speaker_enable_calls(10000, 0);
speaker_enable(10000);
setup_speaker_enable_calls(10000, 0xff);
speaker_enable(10000);
setup_speaker_enable_calls(10000, 91);
speaker_enable(10000);
setup_speaker_enable_calls(10000, -1);
speaker_enable(10000);
}
static void setup_speaker_disable_calls(u8 value)
{
expect_value(inb, port, PC_SPEAKER_PORT);
will_return(inb, value);
expect_value(outb, val, value & 0xfc);
expect_value(outb, port, PC_SPEAKER_PORT);
}
static void test_speaker_disable(void **state)
{
setup_speaker_disable_calls(0);
speaker_disable();
setup_speaker_disable_calls(0xfc);
speaker_disable();
setup_speaker_disable_calls(0xff);
speaker_disable();
setup_speaker_disable_calls(0xff - 0xfc);
speaker_disable();
}
void arch_ndelay(uint64_t ns)
{
check_expected(ns);
}
static void setup_speaker_tone_calls(u16 freq, unsigned int duration)
{
setup_speaker_enable_calls(freq, ~freq & 0xff);
expect_value(arch_ndelay, ns, (uint64_t)duration * NSECS_PER_MSEC);
setup_speaker_disable_calls(0xff);
expect_any(arch_ndelay, ns);
}
static void test_speaker_tone(void **state)
{
setup_speaker_tone_calls(500, 100);
speaker_tone(500, 100);
setup_speaker_tone_calls(4321, 0);
speaker_tone(4321, 0);
setup_speaker_tone_calls(-1, -1);
speaker_tone(-1, -1);
setup_speaker_tone_calls(10000, 1000);
speaker_tone(10000, 1000);
setup_speaker_tone_calls(433, 890);
speaker_tone(433, 890);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_speaker_enable),
cmocka_unit_test(test_speaker_disable),
cmocka_unit_test(test_speaker_tone),
};
return lp_run_group_tests(tests, NULL, NULL);
}
|