[coreboot-gerrit] New patch to review for coreboot: generic: Add a Maxim 98357A codec driver

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Tue May 31 18:55:03 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/15017

-gerrit

commit 9204eb0f591c87b6650ec3d8a5de0f4b0910e0d5
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Wed May 11 11:27:47 2016 -0700

    generic: Add a Maxim 98357A codec driver
    
    The Maxim Integrated 98357A codec is an I2S slave device that has no
    control channel for configuration and instead provides a GPIO that is
    used for channel selection and power down.  This means it does not fit
    into a bus hierarchy easily and is instead represented as a generic
    device and found with a static bus scan using the devicetree.
    
    This driver provides configuration options for passing the "sdmode" GPIO
    descriptor as well as a second option for "sdmode delay" which can
    configure the timing of the sdmode toggling in relation to the I2S
    channel output.
    
    In addition an GPIO can be provided to indicate to the driver whether
    this device is present or not.  This can be used for board designs that
    may have different codec possibilities that are selected by HW strap.
    
    Sample usage for this device driver:
    
    device pci 1f.3 on
      chip drivers/generic/max98357a
        register "sdmode_gpio" = "ACPI_GPIO_OUTPUT(GPP_C6)"
        register "sdmode_delay" = "100"
        device generic 0 on end
      end
    end
    
    Will result in the following code in the SSDT:
    
    Scope (\_SB.PCI0.HDAS) {
      Device (MAXM) {
        Name (_HID, "MX98357A")
        Name (_UID, Zero)
        Name (_DDN, "Maxim Integrated 98357A Amplifier")
        Method (_STA) { Return (0xF) }
        Name (_CRS, ResourceTemplate () {
          GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly,
                  "\\_SB.PCI0.GPIO", 0, ResourceConsumer)
        })
        Name (_DSD, Package () {
          ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
          Package () {
            Package () { "maxim,sdmode-gpio", \_SB.PCI0.HDAS.MAXM, 0, 0, 0 }
            Package () { "maxim,sdmode-delay", 100 }
            Package () { "sdmode-delay", 100 }
          }
        })
      }
    }
    
    Change-Id: Ia0bafe49bea9bbe4a3cc0f9f9cdb6f6390da57b5
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/drivers/generic/max98357a/Kconfig      |   2 +
 src/drivers/generic/max98357a/Makefile.inc |   1 +
 src/drivers/generic/max98357a/chip.h       |  13 ++++
 src/drivers/generic/max98357a/max98357a.c  | 109 +++++++++++++++++++++++++++++
 4 files changed, 125 insertions(+)

diff --git a/src/drivers/generic/max98357a/Kconfig b/src/drivers/generic/max98357a/Kconfig
new file mode 100644
index 0000000..a7104f1
--- /dev/null
+++ b/src/drivers/generic/max98357a/Kconfig
@@ -0,0 +1,2 @@
+config DRIVERS_GENERIC_MAX98357A
+	bool
diff --git a/src/drivers/generic/max98357a/Makefile.inc b/src/drivers/generic/max98357a/Makefile.inc
new file mode 100644
index 0000000..529e24a
--- /dev/null
+++ b/src/drivers/generic/max98357a/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_GENERIC_MAX98357A) += max98357a.c
diff --git a/src/drivers/generic/max98357a/chip.h b/src/drivers/generic/max98357a/chip.h
new file mode 100644
index 0000000..0abd616
--- /dev/null
+++ b/src/drivers/generic/max98357a/chip.h
@@ -0,0 +1,13 @@
+#include <arch/acpi_device.h>
+
+struct drivers_generic_max98357a_config {
+	/* SDMODE GPIO */
+	struct acpi_gpio sdmode_gpio;
+
+	/* SDMODE Delay */
+	unsigned sdmode_delay;
+
+	/* GPIO used to indicate if this device is present */
+	unsigned device_present_gpio;
+	unsigned device_present_gpio_invert;
+};
diff --git a/src/drivers/generic/max98357a/max98357a.c b/src/drivers/generic/max98357a/max98357a.c
new file mode 100644
index 0000000..331df4c
--- /dev/null
+++ b/src/drivers/generic/max98357a/max98357a.c
@@ -0,0 +1,109 @@
+/*
+ * 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_device.h>
+#include <arch/acpigen.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <gpio.h>
+#include <stdint.h>
+#include <string.h>
+#include "chip.h"
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+
+#define MAX98357A_ACPI_NAME	"MAXM"
+#define MAX98357A_ACPI_HID	"MX98357A"
+
+static void max98357a_fill_ssdt(struct device *dev)
+{
+	struct drivers_generic_max98357a_config *config = dev->chip_info;
+	const char *path = acpi_device_path(dev);
+
+	if (!dev->enabled || !path)
+		return;
+
+	/* Device */
+	acpigen_write_scope(acpi_device_scope(dev));
+	acpigen_write_device(acpi_device_name(dev));
+	acpigen_write_name_string("_HID", MAX98357A_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_gpio(&config->sdmode_gpio);
+	acpigen_write_resourcetemplate_footer();
+
+	/* _DSD for devicetree properties */
+	acpi_dp_write_header();
+	/* This points to the first pin in the first gpio entry in _CRS */
+	acpi_dp_write_gpio("maxim,sdmode-gpio", path, 0, 0, 0);
+	/* This is the correctly formatted Device Property name */
+	acpi_dp_write_integer("maxim,sdmode-delay", config->sdmode_delay);
+	/* This is used by the chromium kernel but is not upstream */
+	acpi_dp_write_integer("sdmode-delay", config->sdmode_delay);
+	acpi_dp_write_footer();
+
+	acpigen_pop_len(); /* Device */
+	acpigen_pop_len(); /* Scope */
+
+	printk(BIOS_INFO, "%s: %s\n", path, dev->chip_ops->name);
+}
+
+static const char *max98357a_acpi_name(struct device *dev)
+{
+	return MAX98357A_ACPI_NAME;
+}
+#endif
+
+static struct device_operations max98357a_ops = {
+	.read_resources		  = DEVICE_NOOP,
+	.set_resources		  = DEVICE_NOOP,
+	.enable_resources	  = DEVICE_NOOP,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_name                = &max98357a_acpi_name,
+	.acpi_fill_ssdt_generator = &max98357a_fill_ssdt,
+#endif
+};
+
+static void max98357a_enable(struct device *dev)
+{
+	struct drivers_generic_max98357a_config *config = dev->chip_info;
+
+	/* Check if device is present by reading GPIO */
+	if (config->device_present_gpio) {
+		int present = gpio_get(config->device_present_gpio);
+		present ^= config->device_present_gpio_invert;
+
+		printk(BIOS_INFO, "%s is %spresent\n",
+		       dev->chip_ops->name, present ? "" : "not ");
+
+		if (!present) {
+			dev->enabled = 0;
+			return;
+		}
+	}
+
+	dev->ops = &max98357a_ops;
+}
+
+struct chip_operations drivers_generic_max98357a_ops = {
+	CHIP_NAME("Maxim Integrated 98357A Amplifier")
+	.enable_dev = &max98357a_enable
+};



More information about the coreboot-gerrit mailing list