diff options
author | Dylan Reid <dgreid@chromium.org> | 2011-12-16 10:37:05 -0800 |
---|---|---|
committer | Dylan Reid <dgreid@chromium.org> | 2011-12-16 14:40:59 -0800 |
commit | c4db02fb9289235a0875c6226fe7fd3dd18adf55 (patch) | |
tree | 0af48f2dfa01a1ad47518be0443ef4550b24a045 /board | |
parent | 95711296fae612c0334c889dc6f3183139d7344b (diff) |
Add beep for x86 chormeos.
Implement the VbExBeep function so that the DEV screen can beep.
Much of this code was coppied from coreboot.
BUG=chrome-os-partner:7114
TEST=manual, check that Stumpy beeps on DEV screen timeout and when
booting from USB with dev_boot_usb=0.
Change-Id: Icd4eabb0b10cc3d226db71e6a2b52d3ed7eb25ef
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/13110
Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/chromebook-x86/chromeos/Makefile | 1 | ||||
-rw-r--r-- | board/chromebook-x86/chromeos/hda_codec.c | 145 |
2 files changed, 146 insertions, 0 deletions
diff --git a/board/chromebook-x86/chromeos/Makefile b/board/chromebook-x86/chromeos/Makefile index a3eb6ec90f2..c1e8f71ce04 100644 --- a/board/chromebook-x86/chromeos/Makefile +++ b/board/chromebook-x86/chromeos/Makefile @@ -40,6 +40,7 @@ LIB = $(obj)libchromeos_board.a COBJS-$(CONFIG_CHROMEOS) += cros_gpio.o COBJS-$(CONFIG_CHROMEOS) += power_management.o +COBJS-$(CONFIG_CHROMEOS) += hda_codec.o COBJS := $(COBJS-y) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/chromebook-x86/chromeos/hda_codec.c b/board/chromebook-x86/chromeos/hda_codec.c new file mode 100644 index 00000000000..21a0db5a566 --- /dev/null +++ b/board/chromebook-x86/chromeos/hda_codec.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +/* Implementation of per-board codec beeping */ + +#include <chromeos/hda_codec.h> +#include <common.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <pci.h> + +#define HDA_CMD_REG 0x5C +#define HDA_ICII_REG 0x64 +#define HDA_ICII_BUSY (1 << 0) +#define HDA_ICII_VALID (1 << 1) + +/** + * Wait 50usec for the codec to indicate it is ready + * no response would imply that the codec is non-operative + */ +static int wait_for_ready(uint32_t base) +{ + /* Use a 50 usec timeout - the Linux kernel uses the + * same duration + */ + + int timeout = 50; + + while (timeout--) { + uint32_t reg32 = readl(base + HDA_ICII_REG); + asm("" ::: "memory"); + if (!(reg32 & HDA_ICII_BUSY)) + return 0; + udelay(1); + } + + return -1; +} + +/** + * Wait 50usec for the codec to indicate that it accepted + * the previous command. No response would imply that the code + * is non-operative + */ +static int wait_for_valid(uint32_t base) +{ + uint32_t reg32; + + /* Send the verb to the codec */ + reg32 = readl(base + HDA_ICII_REG); + reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID; + writel(reg32, base + HDA_ICII_REG); + + /* Use a 50 usec timeout - the Linux kernel uses the + * same duration + */ + + int timeout = 50; + while (timeout--) { + reg32 = readl(base + HDA_ICII_REG); + if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == + HDA_ICII_VALID) + return 0; + udelay(1); + } + + return -1; +} + +/* Wait for the codec to be ready, write the verb, then wait for the + * codec to be valid. + */ +int write_one_verb(uint32_t base, uint32_t val) +{ + if (wait_for_ready(base) == -1) + return -1; + + writel(val, base + HDA_CMD_REG); + + if (wait_for_valid(base) == -1) + return -1; + + return 0; +} + +/* Supported sound devices. + */ +static struct pci_device_id supported[] = { + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA}, + {} +}; + +/* Find the base address to talk tot he HDA codec. + */ +static u32 get_hda_base(void) +{ + pci_dev_t devbusfn; + u32 pci_mem_base; + + devbusfn = pci_find_devices(supported, 0); + if (devbusfn < 0) { + printf("Audio: Controller not found !\n"); + return 0; + } + + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base); + pci_mem_base = pci_mem_to_phys(devbusfn, pci_mem_base); + return pci_mem_base; +} + +static const u32 beep_cmd[] = { + 0x00170500, /* power up codec */ + 0x00270500, /* power up DAC */ + 0x00670500, /* power up speaker */ + 0x00670740, /* enable speaker output */ + 0x0023B04B, /* set DAC gain */ + 0x00C70A0C, /* enable beep generator 1 kHz */ +}; + +void enable_beep(void) +{ + uint32_t base; + int i; + + base = get_hda_base(); + for (i = 0; i < sizeof(beep_cmd)/sizeof(beep_cmd[0]); i++) { + if (write_one_verb(base, beep_cmd[i])) + return; + } +} + +void disable_beep(void) +{ + uint32_t base; + + base = get_hda_base(); + write_one_verb(base, 0x00C70A00); /* Disable beep gen */ +} |