Skip to content

Commit 50f1b5f

Browse files
Gé Koerkampjamess-huang
authored andcommitted
Add support for ES90x8 Q2M based DAC board
Change-Id: If70e471d53d3dcac2f22c8f0ea2cf06c0913ceb6 Signed-off-by: Gé Koerkamp <ge.koerkamp@gmail.com> Reviewed-on: https://tp-biosrd-v02/gerrit/83309 Reviewed-by: Jamess Huang(黃以民) <Jamess_Huang@asus.com> Tested-by: Jamess Huang(黃以民) <Jamess_Huang@asus.com>
1 parent fac3727 commit 50f1b5f

File tree

7 files changed

+646
-0
lines changed

7 files changed

+646
-0
lines changed

arch/arm/boot/dts/overlays/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Overlays for the Tinker board platform
22

33
dtbo-$(CONFIG_ARCH_ROCKCHIP) += \
4+
es90x8q2m-dac.dtbo \
45
hifiberry-amp.dtbo \
56
hifiberry-dac.dtbo \
67
hifiberry-dacplus.dtbo \
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Definitions for es90x8q2m dac
2+
/dts-v1/;
3+
/plugin/;
4+
5+
/ {
6+
compatible = "rockchip,rk3288";
7+
8+
fragment@0 {
9+
target-path ="/sound-simple-card";
10+
__overlay__ {
11+
status = "disabled";
12+
};
13+
};
14+
15+
fragment@1 {
16+
target = <&i2c1>;
17+
__overlay__ {
18+
#address-cells = <1>;
19+
#size-cells = <0>;
20+
status = "okay";
21+
22+
i-sabre-codec@48 {
23+
#sound-dai-cells = <0>;
24+
compatible = "xiao,es90x8q2m-i2c";
25+
reg = <0x48>;
26+
status = "okay";
27+
};
28+
};
29+
};
30+
31+
fragment@2 {
32+
target-path = "/sound-ext-card";
33+
es90x8q2m: __overlay__ {
34+
compatible = "xiao,es90x8q2m-dac";
35+
i2s-controller = <&i2s>;
36+
status = "okay";
37+
};
38+
};
39+
40+
fragment@3 {
41+
target = <&hdmi>;
42+
__overlay__ {
43+
hdmi-i2s-audio-disable;
44+
};
45+
};
46+
47+
};

sound/soc/rockchip/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ config SND_SOC_ROCKCHIP_CDNDP
133133
Say Y or M here if you want to add support for SoC audio on Rockchip
134134
boards using CDN DP, such as RK3399 boards.
135135

136+
config SND_SOC_ES90X8Q2M
137+
tristate
138+
139+
config SND_SOC_ES90X8Q2M_I2C
140+
tristate "Support for ESS Technology ES90X8Q2M Series DAC"
141+
depends on I2C
142+
select SND_SOC_ES90X8Q2M
143+
help
144+
Say Y or M if you want to add support for the ESS Technology ES90X8Q2M Series.
145+
136146
config SND_SOC_HIFIBERRY_AMP
137147
tristate "Support for the HifiBerry Amp"
138148
select SND_SOC_TAS5713

sound/soc/rockchip/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ snd-soc-rockchip-multicodecs-objs := rockchip_multicodecs.o
2929
snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
3030
snd-soc-rockchip-rt5651-tc358749x-objs := rockchip_rt5651_tc358749x.o
3131
snd-soc-rockchip-cdndp-objs := rockchip_cdndp.o
32+
snd-soc-es90x8q2m-dac-objs := es90x8q2m-dac.o
33+
snd-soc-es90x8q2m-i2c-objs := es90x8q2m-i2c.o
3234
snd-soc-hifiberry-amp-objs := hifiberry_amp.o
3335
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
3436
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
@@ -48,6 +50,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_MULTICODECS) += snd-soc-rockchip-multicodecs.o
4850
obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o
4951
obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749) += snd-soc-rockchip-rt5651-tc358749x.o
5052
obj-$(CONFIG_SND_SOC_ROCKCHIP_CDNDP) += snd-soc-rockchip-cdndp.o
53+
obj-$(CONFIG_SND_SOC_ES90X8Q2M) += snd-soc-es90x8q2m-dac.o
54+
obj-$(CONFIG_SND_SOC_ES90X8Q2M_I2C) += snd-soc-es90x8q2m-i2c.o
5155
obj-$(CONFIG_SND_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
5256
obj-$(CONFIG_SND_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
5357
obj-$(CONFIG_SND_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o

sound/soc/rockchip/es90x8q2m-dac.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* ASoC Driver for ESS Q2M
3+
*
4+
* Author: Xiao
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* version 2 as published by the Free Software Foundation.
9+
*
10+
* This program is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*/
15+
16+
#include <linux/kernel.h>
17+
#include <linux/init.h>
18+
#include <linux/module.h>
19+
#include <linux/delay.h>
20+
#include <linux/fs.h>
21+
#include <asm/uaccess.h>
22+
#include <sound/core.h>
23+
#include <sound/soc.h>
24+
#include <sound/pcm.h>
25+
#include <sound/pcm_params.h>
26+
27+
#include "es90x8q2m-dac.h"
28+
29+
#ifdef ROCKCHIP_AUDIO
30+
#define ROCKCHIP_I2S_MCLK 512
31+
#endif
32+
33+
static int snd_soc_es90x8q2m_dac_init(struct snd_soc_pcm_runtime *rtd)
34+
{
35+
//struct snd_soc_codec *codec = rtd->codec;
36+
//unsigned int value;
37+
38+
/* Device ID */
39+
//value = snd_soc_read(codec, ES9028Q2M_REG_01);
40+
//dev_info(codec->dev, "xxx Device ID : %02X\n", value);
41+
42+
/* API revision */
43+
//value = snd_soc_read(codec, ES9028Q2M_REG_02);
44+
//dev_info(codec->dev, "xxx API revision : %02X\n", value);
45+
46+
return 0;
47+
}
48+
49+
static int snd_soc_es90x8q2m_dac_hw_params(
50+
struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
51+
{
52+
struct snd_soc_pcm_runtime *rtd = substream->private_data;
53+
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54+
#ifdef ROCKCHIP_AUDIO
55+
unsigned int mclk;
56+
57+
mclk = params_rate(params) * ROCKCHIP_I2S_MCLK;
58+
return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
59+
SND_SOC_CLOCK_OUT);
60+
#else
61+
int bclk_ratio;
62+
63+
bclk_ratio = snd_pcm_format_physical_width(
64+
params_format(params)) * params_channels(params);
65+
return snd_soc_dai_set_bclk_ratio(cpu_dai, bclk_ratio);
66+
#endif
67+
}
68+
69+
/* machine stream operations */
70+
static struct snd_soc_ops snd_soc_es90x8q2m_dac_ops = {
71+
.hw_params = snd_soc_es90x8q2m_dac_hw_params,
72+
};
73+
74+
75+
static struct snd_soc_dai_link snd_rpi_es90x8q2m_dai[] = {
76+
{
77+
.name = "ES90x8Q2M",
78+
.stream_name = "ES90x8Q2M DAC",
79+
.cpu_dai_name = "bcm2708-i2s.0",
80+
.codec_dai_name = "es90x8q2m-dac-dai",
81+
.platform_name = "bcm2708-i2s.0",
82+
.codec_name = "es90x8q2m-codec-i2c.1-0048",
83+
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
84+
| SND_SOC_DAIFMT_CBS_CFS,
85+
.init = snd_soc_es90x8q2m_dac_init,
86+
.ops = &snd_soc_es90x8q2m_dac_ops,
87+
}
88+
};
89+
90+
/* audio machine driver */
91+
static struct snd_soc_card snd_soc_es90x8q2m_dac = {
92+
.name = "ES90x8Q2M DAC",
93+
.owner = THIS_MODULE,
94+
.dai_link = snd_rpi_es90x8q2m_dai,
95+
.num_links = ARRAY_SIZE(snd_rpi_es90x8q2m_dai)
96+
};
97+
98+
99+
static int snd_soc_es90x8q2m_dac_probe(struct platform_device *pdev)
100+
{
101+
int ret = 0;
102+
103+
snd_soc_es90x8q2m_dac.dev = &pdev->dev;
104+
if (pdev->dev.of_node) {
105+
struct device_node *i2s_node;
106+
struct snd_soc_dai_link *dai;
107+
108+
dai = &snd_rpi_es90x8q2m_dai[0];
109+
i2s_node = of_parse_phandle(pdev->dev.of_node,
110+
"i2s-controller", 0);
111+
if (i2s_node) {
112+
dai->cpu_dai_name = NULL;
113+
dai->cpu_of_node = i2s_node;
114+
dai->platform_name = NULL;
115+
dai->platform_of_node = i2s_node;
116+
} else {
117+
dev_err(&pdev->dev,
118+
"Property 'i2s-controller' missing or invalid\n");
119+
return (-EINVAL);
120+
}
121+
122+
dai->name = "ES90x8Q2M";
123+
dai->stream_name = "ES90x8Q2M DAC";
124+
dai->dai_fmt = SND_SOC_DAIFMT_I2S
125+
| SND_SOC_DAIFMT_NB_NF
126+
| SND_SOC_DAIFMT_CBS_CFS;
127+
}
128+
129+
/* Wait for registering codec driver */
130+
mdelay(50);
131+
132+
ret = snd_soc_register_card(&snd_soc_es90x8q2m_dac);
133+
if (ret) {
134+
dev_err(&pdev->dev,
135+
"snd_soc_register_card() failed: %d\n", ret);
136+
}
137+
138+
return ret;
139+
}
140+
141+
static int snd_soc_es90x8q2m_dac_remove(struct platform_device *pdev)
142+
{
143+
return snd_soc_unregister_card(&snd_soc_es90x8q2m_dac);
144+
}
145+
146+
static const struct of_device_id snd_soc_es90x8q2m_dac_of_match[] = {
147+
{ .compatible = "xiao,es90x8q2m-dac", }, //see es90x8q2m-dac-overlay.dts
148+
{}
149+
};
150+
MODULE_DEVICE_TABLE(of, snd_soc_es90x8q2m_dac_of_match);
151+
152+
static struct platform_driver snd_soc_es90x8q2m_dac_driver = {
153+
.driver = {
154+
.name = "snd-soc-es90x8q2m-dac",

sound/soc/rockchip/es90x8q2m-dac.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Driver for ES90x8Q2M
3+
*
4+
* Author: Xiao
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* version 2 as published by the Free Software Foundation.
9+
*
10+
* This program is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*/
15+
16+
#ifndef _SND_SOC_ES90X8Q2M_I2C
17+
#define _SND_SOC_ES90X8Q2M_I2C
18+
19+
20+
/* ES90X8Q2M_I2C Register Address */
21+
#define ES9028Q2M_REG_01 0x01 /* Virtual Device ID : 0x01 = ES90x8Q2M */
22+
#define ES9028Q2M_REG_02 0x02 /* API revision : 0x01 = Revision 01 */
23+
#define ES9028Q2M_REG_10 0x10 /* 0x01 = 352.8kHz or 384kHz, 0x00 = otherwise */
24+
#define ES9028Q2M_REG_20 0x20 /* 0 - 100 (decimal value, 0 = min., 100 = max.) */
25+
#define ES9028Q2M_REG_21 0x21 /* 0x00 = Mute OFF, 0x01 = Mute ON */
26+
#define ES9028Q2M_REG_22 0x22 /* 0x00 = Fast Roll-Off, 0x01 = Slow Roll-Off, 0x02 = Minimum Phase */
27+
#define ES9028Q2M_REG_23 0x23 /* 0x00 = 47.44k, 0x01 = 50kHz, 0x02 = 60kHz, 0x03 = 70kHz */
28+
#define ES9028Q2M_MAX_REG 0x23 /* Maximum Register Number */
29+
30+
#endif /* _SND_SOC_ES90X8Q2M_I2C */

0 commit comments

Comments
 (0)