summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2011-12-16 10:37:05 -0800
committerDylan Reid <dgreid@chromium.org>2011-12-16 14:40:59 -0800
commitc4db02fb9289235a0875c6226fe7fd3dd18adf55 (patch)
tree0af48f2dfa01a1ad47518be0443ef4550b24a045 /board
parent95711296fae612c0334c889dc6f3183139d7344b (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/Makefile1
-rw-r--r--board/chromebook-x86/chromeos/hda_codec.c145
2 files changed, 146 insertions, 0 deletions
diff --git a/board/chromebook-x86/chromeos/Makefile b/board/chromebook-x86/chromeos/Makefile
index a3eb6ec90f..c1e8f71ce0 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 0000000000..21a0db5a56
--- /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 */
+}