From 79a5be820d9b187a1d8617d6a1cb65392448322d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 16 Feb 2019 20:24:58 -0700 Subject: [PATCH] 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 Reviewed-by: Bin Meng --- arch/x86/include/asm/i8254.h | 18 ++++++++++++++++++ arch/x86/lib/i8254.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h index 65c9761..d769daf 100644 --- a/arch/x86/include/asm/i8254.h +++ b/arch/x86/include/asm/i8254.h @@ -35,4 +35,22 @@ /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182 +/** + * i8254_enable_beep() - Start a beep using the PCAT timer + * + * This starts beeping using the legacy i8254 timer. The beep may be silenced + * after a delay with i8254_disable_beep(). + * + * @frequency_hz: Frequency of beep in Hz + * @return 0 if OK, -EINVAL if frequency_hz is 0 + */ +int i8254_enable_beep(uint frequency_hz); + +/** + * i8254_disable_beep() - Disable the bepper + * + * This stops any existing beep + */ +void i8254_disable_beep(void); + #endif /* _ASMI386_I8954_H_ */ 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 #include -#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 @@ int i8254_init(void) */ 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); +} -- 2.7.4