summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/chromebook-x86/chromeos/Makefile1
-rw-r--r--board/chromebook-x86/chromeos/hda_codec.c145
-rw-r--r--include/chromeos/hda_codec.h20
-rw-r--r--include/pci_ids.h1
-rw-r--r--lib/vbexport/utility.c16
5 files changed, 179 insertions, 4 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 */
+}
diff --git a/include/chromeos/hda_codec.h b/include/chromeos/hda_codec.h
new file mode 100644
index 00000000000..e10a0974699
--- /dev/null
+++ b/include/chromeos/hda_codec.h
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/* HDA codec interface for Chrome OS verified boot */
+
+#ifndef CHROMEOS_HDA_CODEC_H_
+#define CHROMEOS_HDA_CODEC_H_
+
+/* Beep control */
+void enable_beep(void);
+void disable_beep(void);
+
+#endif /* CHROMEOS_PHDA_CODEC_H_ */
diff --git a/include/pci_ids.h b/include/pci_ids.h
index dc5016d0c55..fe49c4b4948 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2519,6 +2519,7 @@
#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE 0x1c03
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA 0x1c20
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f
diff --git a/lib/vbexport/utility.c b/lib/vbexport/utility.c
index 6bc53caed1c..90a94be76b1 100644
--- a/lib/vbexport/utility.c
+++ b/lib/vbexport/utility.c
@@ -16,6 +16,7 @@
#include <common.h>
#include <malloc.h>
#include <chromeos/common.h>
+#include <chromeos/hda_codec.h>
#include <chromeos/power_management.h>
/* Import the definition of vboot_wrapper interfaces. */
@@ -89,10 +90,17 @@ void VbExSleepMs(uint32_t msec)
VbError_t VbExBeep(uint32_t msec, uint32_t frequency)
{
- /* TODO Implement it later. */
- VbExSleepMs(msec);
- VBDEBUG("Beep!\n");
- return VBERROR_NO_SOUND;
+ if (frequency)
+ enable_beep();
+ else
+ disable_beep();
+
+ if (msec > 0) {
+ VbExSleepMs(msec);
+ disable_beep();
+ }
+
+ return VBERROR_SUCCESS;
}
int Memcmp(const void *src1, const void *src2, size_t n)