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