[coreboot-gerrit] New patch to review for coreboot: nau8825: Add driver for I2C codec

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Tue May 31 18:54:59 CEST 2016


Duncan Laurie (dlaurie at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15015

-gerrit

commit f0b5867e47e2a69b830b66fa41a8d9654255a6b5
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Tue May 10 20:20:16 2016 -0700

    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 at chromium.org>
    Change-Id: I480d72daf5ac3dded9b1cbb5fbc737b9dfde3834
---
 src/drivers/i2c/nau8825/Kconfig      |   2 +
 src/drivers/i2c/nau8825/Makefile.inc |   1 +
 src/drivers/i2c/nau8825/chip.h       |  96 ++++++++++++++++++++++++++++
 src/drivers/i2c/nau8825/nau8825.c    | 117 +++++++++++++++++++++++++++++++++++
 4 files changed, 216 insertions(+)

diff --git a/src/drivers/i2c/nau8825/Kconfig b/src/drivers/i2c/nau8825/Kconfig
new file mode 100644
index 0000000..d2bdd02
--- /dev/null
+++ b/src/drivers/i2c/nau8825/Kconfig
@@ -0,0 +1,2 @@
+config DRIVERS_I2C_NAU8825
+	bool
diff --git a/src/drivers/i2c/nau8825/Makefile.inc b/src/drivers/i2c/nau8825/Makefile.inc
new file mode 100644
index 0000000..6f32643
--- /dev/null
+++ b/src/drivers/i2c/nau8825/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_I2C_NAU8825) += nau8825.c
diff --git a/src/drivers/i2c/nau8825/chip.h b/src/drivers/i2c/nau8825/chip.h
new file mode 100644
index 0000000..e6c88bc
--- /dev/null
+++ b/src/drivers/i2c/nau8825/chip.h
@@ -0,0 +1,96 @@
+#include <arch/acpi_device.h>
+
+#define NAU8825_MAX_BUTTONS 8
+
+/*
+ * Nuvoton NAU8825 audio codec devicetree bindings
+ * linux/Documentation/devicetree/bindings/sound/nau8825.txt
+ */
+struct drivers_i2c_nau8825_config {
+	/* Interrupt configuration */
+	struct acpi_irq irq;
+
+	/* I2C Bus Frequency in Hertz (default 400kHz) */
+	unsigned bus_speed;
+
+	/* Enable jack detection via JKDET pin */
+	unsigned jkdet_enable;
+
+	/* Enable JKDET pin pull if set, otherwise high impedance state */
+	unsigned jkdet_pull_enable;
+
+	/* Pull-up JKDET pin if set, otherwise pull down */
+	unsigned jkdet_pull_up;
+
+	/* JKDET pin polarity, 0 => active high, 1 => active low */
+	unsigned jkdet_polarity;
+
+	/*
+	 * VREF Impedance selection
+	 *  0 - Open
+	 *  1 - 25 kOhm
+	 *  2 - 125 kOhm
+	 *  3 - 2.5 kOhm
+	 */
+	unsigned vref_impedance;
+
+	/* Button impedance measurement hysteresis */
+	unsigned sar_hysteresis;
+
+	/*
+	 * Reference voltage for button impedance measurement and micbias
+	 *  0 - VDDA
+	 *  1 - VDDA
+	 *  2 - VDDA * 1.1
+	 *  3 - VDDA * 1.2
+	 *  4 - VDDA * 1.3
+	 *  5 - VDDA * 1.4
+	 *  6 - VDDA * 1.53
+	 *  7 - VDDA * 1.53
+	 */
+	unsigned micbias_voltage;
+	unsigned sar_voltage;
+
+	/*
+	 * SAR compare time
+	 *  0 - 500 ns
+	 *  1 - 1 us
+	 *  2 - 2 us
+	 *  3 - 4 us
+	 */
+	unsigned sar_compare_time;
+
+	/*
+	 * SAR sampling time
+	 *  0 - 2 us
+	 *  1 - 4 us
+	 *  2 - 8 us
+	 *  3 - 16 us
+	 */
+	unsigned sar_sampling_time;
+
+	/*
+	 * Button short key press debounce time
+	 *  0 - 30 ms
+	 *  1 - 50 ms
+	 *  2 - 100 ms
+	 *  3 - 30 ms
+	 */
+	unsigned short_key_debounce;
+
+	/* Debounce time 2^(n+2) ms (0-7) for jack insert */
+	unsigned jack_insert_debounce;
+
+	/* Debounce time 2^(n+2) ms (0-7) for jack eject */
+	unsigned jack_eject_debounce;
+
+	/* Number of buttons supported, up to 8 */
+	unsigned sar_threshold_num;
+
+	/*
+	 * Impedance threshold for each button, up to 8
+	 *  SAR = 255 * micbias_voltage / sar_voltage * R / (2000 + R)
+	 *  R is Button impedance
+	 */
+	uint64_t sar_threshold[NAU8825_MAX_BUTTONS];
+};
diff --git a/src/drivers/i2c/nau8825/nau8825.c b/src/drivers/i2c/nau8825/nau8825.c
new file mode 100644
index 0000000..71aacea
--- /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
+};



More information about the coreboot-gerrit mailing list