sound: x86: Add beeping support in i8254

Adjust the code to allow beeping at different frequencies, using a
calculated value for timer 2.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c
index 1f10124..d022795 100644
--- a/arch/x86/lib/i8254.c
+++ b/arch/x86/lib/i8254.c
@@ -8,8 +8,20 @@
 #include <asm/io.h>
 #include <asm/i8254.h>
 
-#define TIMER1_VALUE	18	/* 15.6us */
-#define TIMER2_VALUE	0x0a8e	/* 440Hz */
+#define TIMER1_VALUE		18	/* 15.6us */
+#define BEEP_FREQUENCY_HZ	440
+#define SYSCTL_PORTB		0x61
+#define PORTB_BEEP_ENABLE	0x3
+
+static void i8254_set_beep_freq(uint frequency_hz)
+{
+	uint countdown;
+
+	countdown = PIT_TICK_RATE / frequency_hz;
+
+	outb(countdown & 0xff, PIT_BASE + PIT_T2);
+	outb((countdown >> 8) & 0xff, PIT_BASE + PIT_T2);
+}
 
 int i8254_init(void)
 {
@@ -29,8 +41,23 @@
 	 */
 	outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3,
 	     PIT_BASE + PIT_COMMAND);
-	outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2);
-	outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2);
+	i8254_set_beep_freq(BEEP_FREQUENCY_HZ);
 
 	return 0;
 }
+
+int i8254_enable_beep(uint frequency_hz)
+{
+	if (!frequency_hz)
+		return -EINVAL;
+
+	i8254_set_beep_freq(frequency_hz);
+	setio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE);
+
+	return 0;
+}
+
+void i8254_disable_beep(void)
+{
+	clrio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE);
+}