diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile
index d4f31b76931d69..e859ed32e2d713 100644
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -15,6 +15,7 @@ endif
dtbo-$(RPI_DT_OVERLAYS) += adau1977-adc.dtbo
dtbo-$(RPI_DT_OVERLAYS) += ads1015.dtbo
dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo
+dtbo-$(RPI_DT_OVERLAYS) += akkordion-es9023-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo
dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo
dtbo-$(RPI_DT_OVERLAYS) += audioinjector-wm8731-audio.dtbo
@@ -25,15 +26,18 @@ dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo
dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo
dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo
dtbo-$(RPI_DT_OVERLAYS) += enc28j60.dtbo
+dtbo-$(RPI_DT_OVERLAYS) += es9023-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += gpio-ir.dtbo
dtbo-$(RPI_DT_OVERLAYS) += gpio-poweroff.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo
+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacpluslight-es9023-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi-pro.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo
dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo
+dtbo-$(RPI_DT_OVERLAYS) += i-sabre-dac-es9023-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += i2c-mux.dtbo
dtbo-$(RPI_DT_OVERLAYS) += i2c-pwm-pca9685a.dtbo
@@ -48,6 +52,7 @@ dtbo-$(RPI_DT_OVERLAYS) += iqaudio-digi-wm8804-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += justboom-dac.dtbo
dtbo-$(RPI_DT_OVERLAYS) += justboom-digi.dtbo
dtbo-$(RPI_DT_OVERLAYS) += lirc-rpi.dtbo
+dtbo-$(RPI_DT_OVERLAYS) += mamboberry-dacplus-es9023-audio.dtbo
dtbo-$(RPI_DT_OVERLAYS) += mcp23017.dtbo
dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo
dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo
diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README
index 5e103331e50604..6e48fff33efbf5 100644
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -215,6 +215,26 @@ Params: cs SPI bus Chip Select (default 1)
www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt
+Name: akkordion-es9023-audio
+Info: Configures the Digital Dreamtime Akkordion Music Player (with ESS Sabre
+ ES9023 DAC).
+Load: dtoverlay=akkordion-es9023-audio,
+Params: 384k Instructs the es9023 codec driver to support
+ 352k8 and 384k sample rates.
+ bclk_ratio_int_div Use bclk_ratio=50 for 16/24bps and
+ bclk_ratio=100 for 32bps media when sample
+ rate is a multiple of 8kHz and less than
+ 192kHz. Which causes the selection of the 19M2
+ OSC as the parent for the PCM clock with an
+ integer divider, rather than PLLD with
+ fractional divider and MASH noise shaping.
+ card_name Override the default, "Akkordion", card name.
+ dai_name Override the default, "Akkordion DAC",
+ dai name.
+ dai_stream_name Override the default, "Akkordion DAC HiFi",
+ dai stream name.
+
+
Name: akkordion-iqdacplus
Info: Configures the Digital Dreamtime Akkordion Music Player (based on the
OEM IQAudIO DAC+ or DAC Zero module).
@@ -314,6 +334,24 @@ Params: int_pin GPIO used for INT (default 25)
speed SPI bus speed (default 12000000)
+Name: es9023-audio
+Info: Configures a generic board or HAT using ESS Sabre ES9023 DAC
+Load: dtoverlay=es9023-audio,
+Params: 384k Instructs the es9023 codec driver to support
+ 352k8 and 384k sample rates.
+ bclk_ratio_int_div Use bclk_ratio=50 for 16/24bps and
+ bclk_ratio=100 for 32bps media when sample
+ rate is a multiple of 8kHz and less than
+ 192kHz. Which causes the selection of the 19M2
+ OSC as the parent for the PCM clock with an
+ integer divider, rather than PLLD with
+ fractional divider and MASH noise shaping.
+ card_name Override the default, "es9023", card name.
+ dai_name Override the default, "ES9023 DAC" dai name.
+ dai_stream_name Override the default, "ES9023 DAC HiFi",
+ dai stream name.
+
+
Name: gpio-ir
Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core-
based gpio_ir_recv driver maps received keys directly to a
@@ -376,6 +414,26 @@ Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
master for bit clock and frame clock.
+Name: hifiberry-dacpluslight-es9023-audio
+Info: Configures the HiFiBerry DAC+ Light audio card
+Load: dtoverlay=hifiberry-dacpluslight-es9023-audio,
+Params: 384k Instructs the es9023 codec driver to support
+ 352k8 and 384k sample rates.
+ bclk_ratio_int_div Use bclk_ratio=50 for 16/24bps and
+ bclk_ratio=100 for 32bps media when sample
+ rate is a multiple of 8kHz and less than
+ 192kHz. Which causes the selection of the 19M2
+ OSC as the parent for the PCM clock with an
+ integer divider, rather than PLLD with
+ fractional divider and MASH noise shaping.
+ card_name Override the default, "snd_rpi_hifiberry_dac",
+ card name.
+ dai_name Override the default, "HifiBerry DAC",
+ dai name.
+ dai_stream_name Override the default, "HifiBerry DAC HiFi",
+ dai stream name.
+
+
Name: hifiberry-digi
Info: Configures the HifiBerry Digi and Digi+ audio card
Load: dtoverlay=hifiberry-digi
@@ -426,6 +484,24 @@ Params: speed Display SPI bus speed
ledgpio GPIO used to control backlight
+Name: i-sabre-dac-es9023-audio
+Info: Configures the Audiophonics I-Sabre DAC
+Load: dtoverlay=i-sabre-dac-es9023-audio,
+Params: 384k Instructs the es9023 codec driver to support
+ 352k8 and 384k sample rates.
+ bclk_ratio_int_div Use bclk_ratio=50 for 16/24bps and
+ bclk_ratio=100 for 32bps media when sample
+ rate is a multiple of 8kHz and less than
+ 192kHz. Which causes the selection of the 19M2
+ OSC as the parent for the PCM clock with an
+ integer divider, rather than PLLD with
+ fractional divider and MASH noise shaping.
+ card_name Override the default, "ISabre", card name.
+ dai_name Override the default, "ISabre DAC", dai name.
+ dai_stream_name Override the default, "ISabre DAC HiFi",
+ dai stream name.
+
+
Name: i2c-gpio
Info: Adds support for software i2c controller on gpio pins
Load: dtoverlay=i2c-gpio,=
@@ -619,6 +695,25 @@ Params: gpio_out_pin GPIO for output (default "17")
(default "off")
+Name: mamboberry-dacplus-es9023-audio
+Info: Configures the Collybia Mamboberry HiFi DAC+
+Load: dtoverlay=mamboberry-dacplus-es9023-audio,
+Params: 384k Instructs the es9023 codec driver to support
+ 352k8 and 384k sample rates.
+ bclk_ratio_int_div Use bclk_ratio=50 for 16/24bps and
+ bclk_ratio=100 for 32bps media when sample
+ rate is a multiple of 8kHz and less than
+ 192kHz. Which causes the selection of the 19M2
+ OSC as the parent for the PCM clock with an
+ integer divider, rather than PLLD with
+ fractional divider and MASH noise shaping.
+ card_name Override the default, "Mamboberry", card name.
+ dai_name Override the default, "Mamboberry DAC+",
+ dai name.
+ dai_stream_name Override the default, "Mamboberry DAC+ HiFi",
+ dai stream name.
+
+
Name: mcp23017
Info: Configures the MCP23017 I2C GPIO expander
Load: dtoverlay=mcp23017,=
diff --git a/arch/arm/boot/dts/overlays/akkordion-es9023-audio-overlay.dts b/arch/arm/boot/dts/overlays/akkordion-es9023-audio-overlay.dts
new file mode 100644
index 00000000000000..af9a3bd79e50f1
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/akkordion-es9023-audio-overlay.dts
@@ -0,0 +1,57 @@
+// Definitions for Digital Dreamtime Akkordion using ESS Sabre ES9023 DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ es9023_codec: es9023-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ess,es9023";
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&sound>;
+ es9023_dac: __overlay__ {
+ compatible = "digitaldreamtime,es9023-akkordion-dac";
+ /*
+ * These are the default names that will be
+ * applied by the es9023-dac machine driver
+ * based on the compatible parameter.
+ *
+ * es9023-dac,card-name = "Akkordion"
+ * es9023-dac,dai-name = "Akkordion DAC";
+ * es9023-dac,dai-stream-name = "Akkordion DAC HiFi";
+ */
+ status = "okay";
+ es9023-dac,cpu {
+ sound-dai = <&i2s>;
+ };
+ es9023-dac,codec {
+ sound-dai = <&es9023_codec>;
+ };
+ };
+ };
+
+ __overrides__ {
+ 384k = <&es9023_codec>,"es9023,384k?";
+ bclk_ratio_int_div =
+ <&es9023_dac>,"es9023-dac,bclk-ratio-int-div?";
+ card_name = <&es9023_dac>,"es9023-dac,card-name";
+ dai_name = <&es9023_dac>,"es9023-dac,dai-name";
+ dai_stream_name = <&es9023_dac>,"es9023-dac,dai-stream-name";
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/es9023-audio-overlay.dts b/arch/arm/boot/dts/overlays/es9023-audio-overlay.dts
new file mode 100644
index 00000000000000..842f9853bbcc45
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/es9023-audio-overlay.dts
@@ -0,0 +1,64 @@
+// Definitions for a generic board or HAT using ESS Sabre ES9023 DAC
+
+// NB. Manufacturers of ES9023 DAC boards wishing to use their own ALSA names
+// in preference to the generic names defined here, should copy this
+// file, rename and edit it. Do not change the card, dai, and dai stream
+// names being set below, in this generic es9023-audio overlay!
+// (eg. akkordion-es9023-audio and i-sabre-dac-es9023-audio.)
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ es9023_codec: es9023-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ess,es9023";
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&sound>;
+ es9023_dac: __overlay__ {
+ compatible = "es9023-dac";
+ /*
+ * These are the default names that will be
+ * applied by the es9023-dac machine driver
+ * based on the compatible parameter.
+ *
+ * es9023-dac,card-name = "es9023";
+ * es9023-dac,dai-name = "ES9023 DAC";
+ * es9023-dac,dai-stream-name = "ES9023 DAC HiFi";
+ */
+ status = "okay";
+ es9023-dac,cpu {
+ sound-dai = <&i2s>;
+ };
+ es9023-dac,codec {
+ sound-dai = <&es9023_codec>;
+ };
+ };
+ };
+
+ __overrides__ {
+ 384k = <&es9023_codec>,"es9023,384k?";
+ bclk_ratio_int_div =
+ <&es9023_dac>,"es9023-dac,bclk-ratio-int-div?";
+ card_name = <&es9023_dac>,"es9023-dac,card-name";
+ dai_name = <&es9023_dac>,"es9023-dac,dai-name";
+ dai_stream_name = <&es9023_dac>,"es9023-dac,dai-stream-name";
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacpluslight-es9023-audio-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacpluslight-es9023-audio-overlay.dts
new file mode 100644
index 00000000000000..71d6d294579973
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/hifiberry-dacpluslight-es9023-audio-overlay.dts
@@ -0,0 +1,57 @@
+// Definitions for HiFiBerry DAC+ Light using ESS Sabre ES9023 DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ es9023_codec: es9023-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ess,es9023";
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&sound>;
+ es9023_dac: __overlay__ {
+ compatible = "hifiberry,es9023-dacpluslight";
+ /*
+ * These are the default names that will be
+ * applied by the es9023-dac machine driver
+ * based on the compatible parameter.
+ *
+ * es9023-dac,card-name = "snd_rpi_hifiberry_dac";
+ * es9023-dac,dai-name = "HifiBerry DAC";
+ * es9023-dac,dai-stream-name = "HifiBerry DAC HiFi";
+ */
+ status = "okay";
+ es9023-dac,cpu {
+ sound-dai = <&i2s>;
+ };
+ es9023-dac,codec {
+ sound-dai = <&es9023_codec>;
+ };
+ };
+ };
+
+ __overrides__ {
+ 384k = <&es9023_codec>,"es9023,384k?";
+ bclk_ratio_int_div =
+ <&es9023_dac>,"es9023-dac,bclk-ratio-int-div?";
+ card_name = <&es9023_dac>,"es9023-dac,card-name";
+ dai_name = <&es9023_dac>,"es9023-dac,dai-name";
+ dai_stream_name = <&es9023_dac>,"es9023-dac,dai-stream-name";
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/i-sabre-dac-es9023-audio-overlay.dts b/arch/arm/boot/dts/overlays/i-sabre-dac-es9023-audio-overlay.dts
new file mode 100644
index 00000000000000..9a16dcc53b8d0d
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/i-sabre-dac-es9023-audio-overlay.dts
@@ -0,0 +1,57 @@
+// Definitions for Audiophonics I-Sabre DAC using ESS Sabre ES9023 DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ es9023_codec: es9023-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ess,es9023";
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&sound>;
+ es9023_dac: __overlay__ {
+ compatible = "audiphonics,es9023-i-sabre-dac";
+ /*
+ * These are the default names that will be
+ * applied by the es9023-dac machine driver
+ * based on the compatible parameter.
+ *
+ * es9023-dac,card-name = "ISabre";
+ * es9023-dac,dai-name = "ISabre DAC";
+ * es9023-dac,dai-stream-name = "ISabre DAC HiFi";
+ */
+ status = "okay";
+ es9023-dac,cpu {
+ sound-dai = <&i2s>;
+ };
+ es9023-dac,codec {
+ sound-dai = <&es9023_codec>;
+ };
+ };
+ };
+
+ __overrides__ {
+ 384k = <&es9023_codec>,"es9023,384k?";
+ bclk_ratio_int_div =
+ <&es9023_dac>,"es9023-dac,bclk-ratio-int-div?";
+ card_name = <&es9023_dac>,"es9023-dac,card-name";
+ dai_name = <&es9023_dac>,"es9023-dac,dai-name";
+ dai_stream_name = <&es9023_dac>,"es9023-dac,dai-stream-name";
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/mamboberry-dacplus-es9023-audio-overlay.dts b/arch/arm/boot/dts/overlays/mamboberry-dacplus-es9023-audio-overlay.dts
new file mode 100644
index 00000000000000..047ee2daa71f01
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/mamboberry-dacplus-es9023-audio-overlay.dts
@@ -0,0 +1,57 @@
+// Definitions for Collybia MamboBerry HiFi DAC+ using ESS Sabre ES9023 DAC
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ es9023_codec: es9023-codec {
+ #sound-dai-cells = <0>;
+ compatible = "ess,es9023";
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&sound>;
+ es9023_dac: __overlay__ {
+ compatible = "collybia,es9023-mamboberry-dacplus";
+ /*
+ * These are the default names that will be
+ * applied by the es9023-dac machine driver
+ * based on the compatible parameter.
+ *
+ * es9023-dac,card-name = "Mamboberry";
+ * es9023-dac,dai-name = "Mamboberry DAC+";
+ * es9023-dac,dai-stream-name = "Mamboberry DAC+ HiFi";
+ */
+ status = "okay";
+ es9023-dac,cpu {
+ sound-dai = <&i2s>;
+ };
+ es9023-dac,codec {
+ sound-dai = <&es9023_codec>;
+ };
+ };
+ };
+
+ __overrides__ {
+ 384k = <&es9023_codec>,"es9023,384k?";
+ bclk_ratio_int_div =
+ <&es9023_dac>,"es9023-dac,bclk-ratio-int-div?";
+ card_name = <&es9023_dac>,"es9023-dac,card-name";
+ dai_name = <&es9023_dac>,"es9023-dac,dai-name";
+ dai_stream_name = <&es9023_dac>,"es9023-dac,dai-stream-name";
+ };
+};
diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig
index fafe9d3df0075f..a2babfb9327a74 100644
--- a/arch/arm/configs/bcm2709_defconfig
+++ b/arch/arm/configs/bcm2709_defconfig
@@ -860,6 +860,7 @@ CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_6FIRE=m
CONFIG_SND_SOC=m
CONFIG_SND_BCM2835_SOC_I2S=m
+CONFIG_SND_BCM2708_SOC_ES9023_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
index b1310f6af34296..8b98d2eb07b913 100644
--- a/arch/arm/configs/bcmrpi_defconfig
+++ b/arch/arm/configs/bcmrpi_defconfig
@@ -852,6 +852,7 @@ CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_6FIRE=m
CONFIG_SND_SOC=m
CONFIG_SND_BCM2835_SOC_I2S=m
+CONFIG_SND_BCM2708_SOC_ES9023_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m
CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 8873fd8adce1d1..0891a4e0d9a80c 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -8,6 +8,15 @@ config SND_BCM2835_SOC_I2S
the BCM2835 I2S interface. You will also need
to select the audio interfaces to support below.
+config SND_BCM2708_SOC_ES9023_DAC
+ tristate "Support for ESS Sabre ES9023 DAC"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+ select SND_SOC_ES9023
+ help
+ Say Y or M if you want to add support for boards using the ESS Sabre
+ ES9023 DAC. eg. Audiophonics I-Sabre, Collybia MamboBerry HiFi DAC+,
+ Digital Dreamtime Akkordion and HiFiBerry DAC+ Light.
+
config SND_BCM2708_SOC_HIFIBERRY_DAC
tristate "Support for HifiBerry DAC"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index 17f70f95132223..343dd1f1a3588f 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
# BCM2708 Machine Support
snd-soc-adau1977-adc-objs := adau1977-adc.o
+snd-soc-es9023-dac-objs := es9023_dac.o
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
@@ -21,6 +22,7 @@ snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
snd-soc-dionaudio-loco-objs := dionaudio_loco.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
+obj-$(CONFIG_SND_BCM2708_SOC_ES9023_DAC) += snd-soc-es9023-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
diff --git a/sound/soc/bcm/es9023_dac.c b/sound/soc/bcm/es9023_dac.c
new file mode 100644
index 00000000000000..042453e212f19c
--- /dev/null
+++ b/sound/soc/bcm/es9023_dac.c
@@ -0,0 +1,279 @@
+/*
+ * ASoC Machine Driver for ESS Sabre ES9023 DAC
+ *
+ * Author: Clive Messer
+ * Copyright 2014
+ *
+ * based on the HiFiBerry DAC driver
+ * by Florian Meier Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+struct es9023_dac_priv {
+ bool bclk_ratio_int_div;
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+};
+
+struct es9023_dac_variant {
+ char *compatible;
+ char *card_name;
+ char *dai_name;
+ char *dai_stream_name;
+};
+
+#define COMPAT_GENERIC "es9023-dac"
+#define COMPAT_ISABRE "audiphonics,es9023-i-sabre-dac"
+#define COMPAT_MAMBO "collybia,es9023-mamboberry-dacplus"
+#define COMPAT_AKK "digitaldreamtime,es9023-akkordion-dac"
+#define COMPAT_HBLIGHT "hifiberry,es9023-dacpluslight"
+
+static const struct es9023_dac_variant es9023_dac_variants[] = {
+ { /* generic */
+ .compatible = COMPAT_GENERIC,
+ .card_name = "ES9023",
+ .dai_name = "ES9023 DAC",
+ .dai_stream_name = "ES9023 DAC HiFi",
+ },
+ { /* AudioPhonics ISabre */
+ .compatible = COMPAT_ISABRE,
+ .card_name = "ISabre",
+ .dai_name = "ISabre DAC",
+ .dai_stream_name = "ISabre DAC HiFi",
+ },
+ { /* MamboBerry DAC+ */
+ .compatible = COMPAT_MAMBO,
+ .card_name = "Mamboberry",
+ .dai_name = "Mamboberry DAC",
+ .dai_stream_name = "Mamboberry DAC HiFi",
+ },
+ { /* Digital Dreamtime Akkordion */
+ .compatible = COMPAT_AKK,
+ .card_name = "Akkordion",
+ .dai_name = "Akkordion DAC",
+ .dai_stream_name = "Akkordion DAC HiFi",
+ },
+ { /* HiFiBerry DAC+ Light */
+ .compatible = COMPAT_HBLIGHT,
+ .card_name = "snd_rpi_hifiberry_dac",
+ .dai_name = "HifiBerry DAC",
+ .dai_stream_name = "HifiBerry DAC HiFi",
+ },
+};
+
+static const struct es9023_dac_variant *snd_rpi_es9023_dac_get_variant(
+ struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(es9023_dac_variants); i++) {
+ if (of_device_is_compatible(np,
+ es9023_dac_variants[i].compatible))
+ return &es9023_dac_variants[i];
+ }
+
+ return &es9023_dac_variants[0];
+}
+
+static int snd_rpi_es9023_dac_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct es9023_dac_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ snd_pcm_format_t format = params_format(params);
+ unsigned int sample_bits = snd_pcm_format_width(format);
+ unsigned int sample_freq = params_rate(params);
+ unsigned int channels = params_channels(params);
+ unsigned int physical_bits =
+ snd_pcm_format_physical_width(format);
+ unsigned int bclk_ratio = sample_bits * channels;
+
+ if (priv->bclk_ratio_int_div && channels == 2 &&
+ sample_freq < 192000 && sample_freq % 8000 == 0) {
+ if (sample_bits == 16 || sample_bits == 24)
+ bclk_ratio = 50;
+ else if (sample_bits == 32)
+ bclk_ratio = 100;
+ }
+
+ dev_dbg(rtd->dev, "%s: frequency=%u, format=%s, sample_bits=%u, "
+ "physical_bits=%u, channels=%u. Setting bclk_ratio=%u.\n",
+ __func__, sample_freq, snd_pcm_format_name(format),
+ sample_bits, physical_bits, channels, bclk_ratio);
+
+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bclk_ratio);
+}
+
+/* machine stream operations */
+static struct snd_soc_ops snd_rpi_es9023_dac_ops = {
+ .hw_params = snd_rpi_es9023_dac_hw_params,
+};
+
+static int snd_rpi_es9023_dac_sub_parse_of(struct device_node *np,
+ struct device_node **p_node, const char **name)
+{
+ struct of_phandle_args args;
+ int ret;
+
+ ret = of_parse_phandle_with_args(np, "sound-dai",
+ "#sound-dai-cells", 0, &args);
+ if (ret)
+ return ret;
+
+ *p_node = args.np;
+
+ ret = snd_soc_of_get_dai_name(np, name);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int snd_rpi_es9023_dac_probe(struct platform_device *pdev)
+{
+ char prop[128];
+ char *prefix = "es9023-dac,";
+ const struct es9023_dac_variant *variant;
+ struct device_node *codec_np, *cpu_np, *np = pdev->dev.of_node;
+ struct es9023_dac_priv *priv;
+ int ret = 0;
+
+ snprintf(prop, sizeof(prop), "%scpu", prefix);
+ cpu_np = of_get_child_by_name(np, prop);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "%s: failed to find %s DT node\n",
+ __func__, prop);
+ ret = -EINVAL;
+ goto cpu_end;
+ }
+
+ snprintf(prop, sizeof(prop), "%scodec", prefix);
+ codec_np = of_get_child_by_name(np, prop);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "%s: failed to find %s DT node\n",
+ __func__, prop);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ /* priv->dai.cpu_dai_name = "bcm2708-i2s.0"; */
+ ret = snd_rpi_es9023_dac_sub_parse_of(cpu_np,
+ &priv->dai.cpu_of_node,
+ &priv->dai.cpu_dai_name);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "%s: failed to get cpu dai name: %d\n",
+ __func__, ret);
+ goto end;
+ }
+ priv->dai.cpu_dai_name = NULL;
+
+ /* priv->dai.platform_name = "bcm2708-i2s.0"; */
+ priv->dai.platform_of_node = priv->dai.cpu_of_node;
+
+ /* priv->dai.codec_name = "es9023-codec"; */
+ /* priv->dai.codec_dai_name = "es9023-hifi"; */
+ ret = snd_rpi_es9023_dac_sub_parse_of(codec_np,
+ &priv->dai.codec_of_node,
+ &priv->dai.codec_dai_name);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "%s: failed to get codec dai name: %d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ priv->dai.dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS;
+
+ priv->dai.ops = &snd_rpi_es9023_dac_ops;
+
+ priv->card.dai_link = &priv->dai;
+ priv->card.dev = &pdev->dev;
+ priv->card.num_links = 1;
+ priv->card.owner = THIS_MODULE;
+
+ snprintf(prop, sizeof(prop), "%sbclk-ratio-int-div", prefix);
+ priv->bclk_ratio_int_div = of_property_read_bool(np, prop);
+
+ variant = snd_rpi_es9023_dac_get_variant(np);
+
+ snprintf(prop, sizeof(prop), "%scard-name", prefix);
+ if (of_property_read_string(np, prop, &priv->card.name))
+ priv->card.name = variant->card_name;
+
+ snprintf(prop, sizeof(prop), "%sdai-name", prefix);
+ if (of_property_read_string(np, prop, &priv->dai.name))
+ priv->dai.name = variant->dai_name;
+
+ snprintf(prop, sizeof(prop), "%sdai-stream-name", prefix);
+ if (of_property_read_string(np, prop, &priv->dai.stream_name))
+ priv->dai.stream_name = variant->dai_stream_name;
+
+ platform_set_drvdata(pdev, &priv->card);
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
+ if (ret)
+ dev_err(&pdev->dev, "%s: snd_soc_register_card failed: %d\n",
+ __func__, ret);
+
+end:
+ of_node_put(codec_np);
+cpu_end:
+ of_node_put(cpu_np);
+
+ return ret;
+}
+
+static const struct of_device_id snd_rpi_es9023_dac_of_match[] = {
+ /* generic */
+ { .compatible = COMPAT_GENERIC, },
+ /* Manufacturer compatible definitions BELOW! */
+ { .compatible = COMPAT_ISABRE, },
+ { .compatible = COMPAT_MAMBO, },
+ { .compatible = COMPAT_AKK, },
+ { .compatible = COMPAT_HBLIGHT, },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, snd_rpi_es9023_dac_of_match);
+
+static struct platform_driver snd_rpi_es9023_dac_driver = {
+ .driver = {
+ .name = "snd-es9023-dac",
+ .owner = THIS_MODULE,
+ .of_match_table = snd_rpi_es9023_dac_of_match,
+ },
+ .probe = snd_rpi_es9023_dac_probe,
+};
+
+module_platform_driver(snd_rpi_es9023_dac_driver);
+
+MODULE_AUTHOR("Clive Messer ");
+MODULE_DESCRIPTION("ASoC ESS Sabre ES9023 card driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index fe32ccaaaebe9c..e31144d96c458c 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -65,6 +65,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_BT_SCO
select SND_SOC_ES8328_SPI if SPI_MASTER
select SND_SOC_ES8328_I2C if I2C
+ select SND_SOC_ES9023
select SND_SOC_GTM601
select SND_SOC_ICS43432
select SND_SOC_ISABELLE if I2C
@@ -468,6 +469,9 @@ config SND_SOC_ES8328_SPI
tristate
select SND_SOC_ES8328
+config SND_SOC_ES9023
+ tristate "ESS Sabre ES9023 CODEC"
+
config SND_SOC_GTM601
tristate 'GTM601 UMTS modem audio codec'
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dbb213da41a16e..3750265e9aa00a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -58,6 +58,7 @@ snd-soc-dmic-objs := dmic.o
snd-soc-es8328-objs := es8328.o
snd-soc-es8328-i2c-objs := es8328-i2c.o
snd-soc-es8328-spi-objs := es8328-spi.o
+snd-soc-es9023-objs := es9023.o
snd-soc-gtm601-objs := gtm601.o
snd-soc-ics43432-objs := ics43432.o
snd-soc-isabelle-objs := isabelle.o
@@ -256,6 +257,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
+obj-$(CONFIG_SND_SOC_ES9023) += snd-soc-es9023.o
obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
diff --git a/sound/soc/codecs/es9023.c b/sound/soc/codecs/es9023.c
new file mode 100644
index 00000000000000..0268516fa51874
--- /dev/null
+++ b/sound/soc/codecs/es9023.c
@@ -0,0 +1,141 @@
+/*
+ * Driver for the ESS ES9023 codec
+ *
+ * Author: Clive Messer
+ * Copyright 2014
+ *
+ * based on the PCM1794A codec driver
+ * by Florian Meier Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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
+#include
+#include
+
+#include
+
+struct es9023_priv {
+ bool rates_384k;
+};
+
+static const u32 es9023_rates[] = {
+ 32000, 44100, 48000, 88200, 96000, 176400, 192000,
+};
+
+static const struct snd_pcm_hw_constraint_list es9023_constraint_rates = {
+ .count = ARRAY_SIZE(es9023_rates),
+ .list = es9023_rates,
+};
+
+static const u32 es9023_8x_rates[] = {
+ 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000,
+};
+
+static const struct snd_pcm_hw_constraint_list es9023_8x_constraint_rates = {
+ .count = ARRAY_SIZE(es9023_8x_rates),
+ .list = es9023_8x_rates,
+};
+
+static int es9023_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct es9023_priv *priv = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+
+ dev_dbg(codec->dev, "%s: set rates (32k-%s) constraint\n", __func__,
+ ((priv->rates_384k) ? "384k" : "192k"));
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ ((priv->rates_384k)
+ ? &es9023_8x_constraint_rates
+ : &es9023_constraint_rates));
+ if (ret != 0) {
+ dev_err(codec->dev, "%s: Failed to set rates constraint: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops es9023_dai_ops = {
+ .startup = es9023_dai_startup,
+};
+
+static struct snd_soc_dai_driver es9023_dai = {
+ .name = "es9023-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE
+ },
+ .ops = &es9023_dai_ops,
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_es9023;
+
+static int es9023_probe(struct platform_device *pdev)
+{
+ struct es9023_priv *priv;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node)
+ priv->rates_384k = of_property_read_bool(pdev->dev.of_node,
+ "es9023,384k");
+#endif
+
+ dev_set_drvdata(&pdev->dev, priv);
+
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_es9023,
+ &es9023_dai, 1);
+}
+
+static int es9023_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id es9023_of_match[] = {
+ { .compatible = "ess,es9023", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, es9023_of_match);
+
+static struct platform_driver es9023_codec_driver = {
+ .probe = es9023_probe,
+ .remove = es9023_remove,
+ .driver = {
+ .name = "es9023-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = es9023_of_match,
+ },
+};
+
+module_platform_driver(es9023_codec_driver);
+
+MODULE_AUTHOR("Clive Messer ");
+MODULE_DESCRIPTION("ASoC ESS Sabre ES9023 codec driver");
+MODULE_LICENSE("GPL v2");