
Hi Bin,
On Tue, 30 Jun 2020 at 00:06, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Mon, Jun 15, 2020 at 11:57 AM Simon Glass sjg@chromium.org wrote:
This chip is used on coral and we need to generate ACPI tables for sound to make it work. Add a driver that does just this (i.e. at present does not actually support playing sound).
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v1:
- Use acpi,ddn instead of acpi,desc
- Add a check for invalid node
- Add NHLT support
- Capitalise ACPI_OPS_PTR
- Rebase to master
configs/sandbox_defconfig | 1 + doc/device-tree-bindings/sound/da7219.txt | 113 +++++++++++++ drivers/sound/Kconfig | 9 ++ drivers/sound/Makefile | 1 + drivers/sound/da7219.c | 189 ++++++++++++++++++++++ 5 files changed, 313 insertions(+) create mode 100644 doc/device-tree-bindings/sound/da7219.txt create mode 100644 drivers/sound/da7219.c
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cb6b4b0ee7..6368e278f2 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -202,6 +202,7 @@ CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y CONFIG_SOUND=y +CONFIG_SOUND_DA7219=y CONFIG_SOUND_SANDBOX=y CONFIG_SANDBOX_SPI=y CONFIG_SPMI=y diff --git a/doc/device-tree-bindings/sound/da7219.txt b/doc/device-tree-bindings/sound/da7219.txt new file mode 100644 index 0000000000..5fd8a9f1e7 --- /dev/null +++ b/doc/device-tree-bindings/sound/da7219.txt @@ -0,0 +1,113 @@ +Dialog Semiconductor DA7219 Audio Codec bindings
+DA7219 is an audio codec with advanced accessory detect features.
+======
+Required properties: +- compatible : Should be "dlg,da7219" +- reg: Specifies the I2C slave address
+- interrupts : IRQ line info for DA7219.
- (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
- further information relating to interrupt properties)
+- VDD-supply: VDD power supply for the device +- VDDMIC-supply: VDDMIC power supply for the device +- VDDIO-supply: VDDIO power supply for the device
- (See Documentation/devicetree/bindings/regulator/regulator.txt for further
- information relating to regulators)
+Optional properties: +- interrupt-names : Name associated with interrupt line. Should be "wakeup" if
- interrupt is to be used to wake system, otherwise "irq" should be used.
+- wakeup-source: Flag to indicate this device can wake system (suspend/resume).
+- #clock-cells : Should be set to '<0>', only one clock source provided; +- clock-output-names : Name given for DAI clocks output;
+- clocks : phandle and clock specifier for codec MCLK. +- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
+- dlg,micbias-lvl : Voltage (mV) for Mic Bias
[<1600>, <1800>, <2000>, <2200>, <2400>, <2600>]
+- dlg,mic-amp-in-sel : Mic input source type
["diff", "se_p", "se_n"]
+- dlg,mclk-name : String name of MCLK for ACPI
+Deprecated properties: +- dlg,ldo-lvl : Required internal LDO voltage (mV) level for digital engine
- (LDO unavailable in production HW so property no longer required).
+======
+Child node - 'da7219_aad':
+Optional properties: +- dlg,micbias-pulse-lvl : Mic bias higher voltage pulse level (mV).
[<2800>, <2900>]
+- dlg,micbias-pulse-time : Mic bias higher voltage pulse duration (ms) +- dlg,btn-cfg : Periodic button press measurements for 4-pole jack (ms)
[<2>, <5>, <10>, <50>, <100>, <200>, <500>]
+- dlg,mic-det-thr : Impedance threshold for mic detection measurement (Ohms)
[<200>, <500>, <750>, <1000>]
+- dlg,jack-ins-deb : Debounce time for jack insertion (ms)
[<5>, <10>, <20>, <50>, <100>, <200>, <500>, <1000>]
+- dlg,jack-det-rate: Jack type detection latency (3/4 pole)
["32ms_64ms", "64ms_128ms", "128ms_256ms", "256ms_512ms"]
+- dlg,jack-rem-deb : Debounce time for jack removal (ms)
[<1>, <5>, <10>, <20>]
+- dlg,a-d-btn-thr : Impedance threshold between buttons A and D
[0x0 - 0xFF]
+- dlg,d-b-btn-thr : Impedance threshold between buttons D and B
[0x0 - 0xFF]
+- dlg,b-c-btn-thr : Impedance threshold between buttons B and C
[0x0 - 0xFF]
+- dlg,c-mic-btn-thr : Impedance threshold between button C and Mic
[0x0 - 0xFF]
+- dlg,btn-avg : Number of 8-bit readings for averaged button measurement
[<1>, <2>, <4>, <8>]
+- dlg,adc-1bit-rpt : Repeat count for 1-bit button measurement
[<1>, <2>, <4>, <8>]
+======
+Example:
codec: da7219@1a {
compatible = "dlg,da7219";
reg = <0x1a>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
VDD-supply = <®_audio>;
VDDMIC-supply = <®_audio>;
VDDIO-supply = <®_audio>;
#clock-cells = <0>;
clock-output-names = "dai-clks";
clocks = <&clks 201>;
clock-names = "mclk";
dlg,ldo-lvl = <1200>;
dlg,micbias-lvl = <2600>;
dlg,mic-amp-in-sel = "diff";
da7219_aad {
dlg,btn-cfg = <50>;
dlg,mic-det-thr = <500>;
dlg,jack-ins-deb = <20>;
dlg,jack-det-rate = "32ms_64ms";
dlg,jack-rem-deb = <1>;
dlg,a-d-btn-thr = <0xa>;
dlg,d-b-btn-thr = <0x16>;
dlg,b-c-btn-thr = <0x21>;
dlg,c-mic-btn-thr = <0x3E>;
dlg,btn-avg = <4>;
dlg,adc-1bit-rpt = <1>;
};
};
diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig index 4ebc719be2..7f214b97be 100644 --- a/drivers/sound/Kconfig +++ b/drivers/sound/Kconfig @@ -40,6 +40,15 @@ config I2S_SAMSUNG option provides an implementation for sound_init() and sound_play().
+config SOUND_DA7219
bool "Dialog Semiconductor audio codec"
depends on SOUND
help
The DA7219 is an ultra-low-power audio codec with Advanced Accessory
Detection (AAD). This driver only supports generation of ACPI tables.
It does not support sound output or any of the other codec
features.
config SOUND_I8254 bool "Intel i8254 timer / beeper" depends on SOUND diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 73ed7fe53c..8c3933ad15 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_SOUND) += sound.o obj-$(CONFIG_SOUND) += codec-uclass.o obj-$(CONFIG_SOUND) += i2s-uclass.o obj-$(CONFIG_SOUND) += sound-uclass.o +obj-$(CONFIG_SOUND_DA7219) += da7219.o obj-$(CONFIG_I2S_SAMSUNG) += samsung-i2s.o obj-$(CONFIG_SOUND_SANDBOX) += sandbox.o obj-$(CONFIG_I2S_ROCKCHIP) += rockchip_i2s.o rockchip_sound.o diff --git a/drivers/sound/da7219.c b/drivers/sound/da7219.c new file mode 100644 index 0000000000..454e2591ed --- /dev/null +++ b/drivers/sound/da7219.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- ACPI driver for DA7219 codec
- Copyright 2019 Google LLC
- Parts taken from coreboot
- */
+#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <irq.h> +#include <log.h> +#include <acpi/acpigen.h> +#include <acpi/acpi_device.h> +#include <acpi/acpi_dp.h> +#ifdef CONFIG_X86 +#include <asm/acpi_nhlt.h> +#endif +#include <asm-generic/gpio.h> +#include <dt-bindings/sound/nhlt.h> +#include <dm/acpi.h>
+#define DA7219_ACPI_HID "DLGS7219"
+static int da7219_acpi_fill_ssdt(const struct udevice *dev,
struct acpi_ctx *ctx)
+{
char scope[ACPI_PATH_MAX];
char name[ACPI_NAME_MAX];
struct acpi_dp *dsd, *aad;
ofnode node;
u32 val;
int ret;
ret = acpi_device_scope(dev, scope, sizeof(scope));
if (ret)
return log_msg_ret("scope", ret);
ret = acpi_get_name(dev, name);
if (ret)
return log_msg_ret("name", ret);
/* Device */
acpigen_write_scope(ctx, scope);
acpigen_write_device(ctx, name);
acpigen_write_name_string(ctx, "_HID", DA7219_ACPI_HID);
acpigen_write_name_integer(ctx, "_UID", 1);
acpigen_write_name_string(ctx, "_DDN",
dev_read_string(dev, "acpi,ddn"));
acpigen_write_name_integer(ctx, "_S0W", 4);
acpigen_write_sta(ctx, acpi_device_status(dev));
/* Resources */
acpigen_write_name(ctx, "_CRS");
acpigen_write_resourcetemplate_header(ctx);
ret = acpi_device_write_i2c_dev(ctx, dev);
if (ret)
return log_msg_ret("i2c", ret);
/* Use either Interrupt() or GpioInt() */
ret = acpi_device_write_interrupt_or_gpio(ctx, (struct udevice *)dev,
"req-gpios");
if (ret)
return log_msg_ret("irq_gpio", ret);
acpigen_write_resourcetemplate_footer(ctx);
/* AAD Child Device Properties */
aad = acpi_dp_new_table("DAAD");
if (!aad)
return log_msg_ret("aad", -ENOMEM);
node = ofnode_find_subnode(dev_ofnode(dev), "da7219_aad");
if (!ofnode_valid(node))
return log_msg_ret("da7219_aad", -EINVAL);
acpi_dp_ofnode_copy_int(node, aad, "dlg,btn-cfg");
acpi_dp_ofnode_copy_int(node, aad, "dlg,mic-det-thr");
acpi_dp_ofnode_copy_int(node, aad, "dlg,jack-ins-deb");
acpi_dp_ofnode_copy_str(node, aad, "dlg,jack-det-rate");
acpi_dp_ofnode_copy_int(node, aad, "dlg,jack-rem-deb");
acpi_dp_ofnode_copy_int(node, aad, "dlg,a-d-btn-thr");
acpi_dp_ofnode_copy_int(node, aad, "dlg,d-b-btn-thr");
acpi_dp_ofnode_copy_int(node, aad, "dlg,b-c-btn-thr");
acpi_dp_ofnode_copy_int(node, aad, "dlg,c-mic-btn-thr");
acpi_dp_ofnode_copy_int(node, aad, "dlg,btn-avg");
acpi_dp_ofnode_copy_int(node, aad, "dlg,adc-1bit-rpt");
if (!ofnode_read_u32(node, "dlg,micbias-pulse-lvl", &val)) {
acpi_dp_ofnode_copy_int(node, aad, "dlg,micbias-pulse-lvl");
acpi_dp_ofnode_copy_int(node, aad, "dlg,micbias-pulse-time");
}
/* DA7219 Properties */
dsd = acpi_dp_new_table("_DSD");
if (!dsd)
return log_msg_ret("dsd", -ENOMEM);
acpi_dp_dev_copy_int(dev, dsd, "dlg,micbias-lvl");
acpi_dp_dev_copy_str(dev, dsd, "dlg,mic-amp-in-sel");
acpi_dp_dev_copy_str(dev, dsd, "dlg,mclk-name");
acpi_dp_add_child(dsd, "da7219_aad", aad);
/* Write Device Property Hierarchy */
acpi_dp_write(ctx, dsd);
acpigen_pop_len(ctx); /* Device */
acpigen_pop_len(ctx); /* Scope */
return 0;
+}
+#ifdef CONFIG_X86
Is the following not applied to non-x86 board?
As far as I know this is only supported on X86. This is an Intel standard, starting with Skylake. I will add a comment.
+static const struct nhlt_format_config da7219_formats[] = {
/* 48 KHz 24-bits per sample. */
{
.num_channels = 2,
.sample_freq_khz = 48,
.container_bits_per_sample = 32,
.valid_bits_per_sample = 24,
.settings_file = "dialog-2ch-48khz-24b.dat",
},
+};
+static const struct nhlt_tdm_config tdm_config = {
.virtual_slot = 0,
.config_type = NHLT_TDM_BASIC,
+};
+static const struct nhlt_endp_descriptor da7219_descriptors[] = {
/* Render Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_RENDER,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.cfg = &tdm_config,
.cfg_size = sizeof(tdm_config),
.formats = da7219_formats,
.num_formats = ARRAY_SIZE(da7219_formats),
},
/* Capture Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_CAPTURE,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.cfg = &tdm_config,
.cfg_size = sizeof(tdm_config),
.formats = da7219_formats,
.num_formats = ARRAY_SIZE(da7219_formats),
},
+};
+static int da7219_acpi_setup_nhlt(const struct udevice *dev,
struct acpi_ctx *ctx)
+{
u32 hwlink;
int ret;
if (dev_read_u32(dev, "acpi,audio-link", &hwlink))
return log_msg_ret("link", -EINVAL);
/* Virtual bus id of SSP links are the hardware port ids proper. */
ret = nhlt_add_ssp_endpoints(ctx->nhlt, hwlink, da7219_descriptors,
Where is this nhlt_add_ssp_endpoints() defined?
In a later patch. I will move it earlier.
ARRAY_SIZE(da7219_descriptors));
if (ret)
return log_msg_ret("add", ret);
return 0;
+} +#endif
+struct acpi_ops da7219_acpi_ops = {
.fill_ssdt = da7219_acpi_fill_ssdt,
+#ifdef CONFIG_X86
.setup_nhlt = da7219_acpi_setup_nhlt,
+#endif +};
+static const struct udevice_id da7219_ids[] = {
{ .compatible = "dlg,da7219" },
{ }
+};
+U_BOOT_DRIVER(da7219) = {
.name = "da7219",
.id = UCLASS_MISC,
.of_match = da7219_ids,
ACPI_OPS_PTR(&da7219_acpi_ops)
+};
Regards, SImon