aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/i2c/nau8825/nau8825.c
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2016-05-10 20:20:16 -0700
committerMartin Roth <martinroth@google.com>2016-06-01 22:28:29 +0200
commit7522dc3c072b9ef09363afd6a699cdb0564f9865 (patch)
tree144fd59d4878a152d8ffaa011c7fb2c26836bf81 /src/drivers/i2c/nau8825/nau8825.c
parent16f3d3d35f4fb7b70fd45399ad52ba3129719133 (diff)
nau8825: Add driver for I2C codec
The Nuvoton NAU8825 audio codec is an I2C device that has a number of tunable parameters that can be provided to the kernel device driver for basic configuration and optimal operation. The configuration options are exposed to devicetree as registers and then presented as Device Properties via ACPI to the operation system. This sample configuration in devicetree: device pci 19.2 on chip drivers/i2c/nau8825 register "irq" = "IRQ_LEVEL_LOW(GPP_F10_IRQ)" register "jkdet_enable" = "1" register "sar_threshold_num" = "2" register "sar_threshold[0]" = "0x0c" register "sar_threshold[1]" = "0x1c" device i2c 1a on end end end Will generate the following code in the SSDT, trimmed for this commit message as there are more properties that can be configured: Scope (\_SB.PCI0.I2C4) { Name (_HID, "10508825") Name (_UID, Zero) Name (_DDN, "Nuvoton NAU8825 Codec") Method (_STA) { Return (0xF) } Name (_CRS, ResourceTemplate () { I2cSerialBus (0x1A, ControllerInitiated, 0x61A80, AddressingMode7Bit, "\_SB.PCI0.I2C4", 0, ResourceConsumer) Interrupt (ResourceConsumer, Level, ActiveLow) { 0x3A } }) Name (_DSD, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bff4aa301"), Package () { Package () { "nuvoton,jkdet-enable", 1 }, Package () { "nuvoton,sar-threshold-num", 2 }, Package () { "nuvoton,sar-threshold", Package () { 0x0c, 0x1c } } } }) } Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Change-Id: I480d72daf5ac3dded9b1cbb5fbc737b9dfde3834 Reviewed-on: https://review.coreboot.org/15015 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/drivers/i2c/nau8825/nau8825.c')
-rw-r--r--src/drivers/i2c/nau8825/nau8825.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/drivers/i2c/nau8825/nau8825.c b/src/drivers/i2c/nau8825/nau8825.c
new file mode 100644
index 0000000000..71aaceaf15
--- /dev/null
+++ b/src/drivers/i2c/nau8825/nau8825.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi.h>
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
+#include <console/console.h>
+#include <device/i2c.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <stdint.h>
+#include <string.h>
+#include "chip.h"
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+
+#define NAU8825_ACPI_NAME "NAU8"
+#define NAU8825_ACPI_HID "10508825"
+#define NAU8825_DP_INT(key,val) acpi_dp_write_integer("nuvoton," key, (val))
+
+static void nau8825_fill_ssdt(struct device *dev)
+{
+ struct drivers_i2c_nau8825_config *config = dev->chip_info;
+ const char *scope = acpi_device_scope(dev);
+ struct acpi_i2c i2c = {
+ .address = dev->path.i2c.device,
+ .mode_10bit = dev->path.i2c.mode_10bit,
+ .speed = config->bus_speed ? : I2C_SPEED_FAST,
+ .resource = scope,
+ };
+
+ if (!dev->enabled || !scope)
+ return;
+ if (config->sar_threshold_num > NAU8825_MAX_BUTTONS)
+ return;
+
+ /* Device */
+ acpigen_write_scope(scope);
+ acpigen_write_device(acpi_device_name(dev));
+ acpigen_write_name_string("_HID", NAU8825_ACPI_HID);
+ acpigen_write_name_integer("_UID", 0);
+ acpigen_write_name_string("_DDN", dev->chip_ops->name);
+ acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
+
+ /* Resources */
+ acpigen_write_name("_CRS");
+ acpigen_write_resourcetemplate_header();
+ acpi_device_write_i2c(&i2c);
+ acpi_device_write_interrupt(&config->irq);
+ acpigen_write_resourcetemplate_footer();
+
+ /* Device Properties */
+ acpi_dp_write_header();
+ NAU8825_DP_INT("jkdet-enable", config->jkdet_enable);
+ NAU8825_DP_INT("jkdet-pull-enable", config->jkdet_pull_enable);
+ NAU8825_DP_INT("jkdet-pull-up", config->jkdet_pull_up);
+ NAU8825_DP_INT("jkdet-polarity", config->jkdet_polarity);
+ NAU8825_DP_INT("vref-impedance", config->vref_impedance);
+ NAU8825_DP_INT("micbias-voltage", config->micbias_voltage);
+ NAU8825_DP_INT("sar-hysteresis", config->sar_hysteresis);
+ NAU8825_DP_INT("sar-voltage", config->sar_voltage);
+ NAU8825_DP_INT("sar-compare-time", config->sar_compare_time);
+ NAU8825_DP_INT("sar-sampling-time", config->sar_sampling_time);
+ NAU8825_DP_INT("short-key-debounce", config->short_key_debounce);
+ NAU8825_DP_INT("jack-insert-debounce", config->jack_insert_debounce);
+ NAU8825_DP_INT("jack-eject-deboune", config->jack_eject_debounce);
+ NAU8825_DP_INT("sar-threshold-num", config->sar_threshold_num);
+ acpi_dp_write_integer_array("nuvoton,sar-threshold",
+ config->sar_threshold,
+ config->sar_threshold_num);
+ acpi_dp_write_footer();
+
+ acpigen_pop_len(); /* Device */
+ acpigen_pop_len(); /* Scope */
+
+ printk(BIOS_INFO, "%s: %s address 0%xh irq %d\n",
+ acpi_device_path(dev), dev->chip_ops->name,
+ dev->path.i2c.device, config->irq.pin);
+}
+
+static const char *nau8825_acpi_name(struct device *dev)
+{
+ return NAU8825_ACPI_NAME;
+}
+#endif
+
+static struct device_operations nau8825_ops = {
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ .acpi_name = &nau8825_acpi_name,
+ .acpi_fill_ssdt_generator = &nau8825_fill_ssdt,
+#endif
+};
+
+static void nau8825_enable(struct device *dev)
+{
+ dev->ops = &nau8825_ops;
+}
+
+struct chip_operations drivers_i2c_nau8825_ops = {
+ CHIP_NAME("Nuvoton NAU8825 Codec")
+ .enable_dev = &nau8825_enable
+};