summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-01-26 16:44:08 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit5c10c08aea955461372c5fe15a34d86e0c33c840 (patch)
tree1823bee7c69a819c69252089b9c1407c1f59b60e /sound/soc/codecs
parent43a2f9035348498043ab3f0fe835d8a1074dd618 (diff)
MLK-17470: ASoC: ak4497: automatically select dsdsel in driver
automatically select dsdsel in driver according to the frequency Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/ak4497.c36
-rw-r--r--sound/soc/codecs/ak4497.h13
2 files changed, 49 insertions, 0 deletions
diff --git a/sound/soc/codecs/ak4497.c b/sound/soc/codecs/ak4497.c
index 74145a63ebcd..1eb6d40fe085 100644
--- a/sound/soc/codecs/ak4497.c
+++ b/sound/soc/codecs/ak4497.c
@@ -488,6 +488,8 @@ static int ak4497_hw_params(struct snd_pcm_substream *substream,
u8 dfs2;
int nfs1;
bool is_dsd = false;
+ int dsd_bclk;
+ u8 dsdsel0, dsdsel1;
if (pcm_format == SNDRV_PCM_FORMAT_DSD_U8 ||
pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE ||
@@ -505,6 +507,13 @@ static int ak4497_hw_params(struct snd_pcm_substream *substream,
dfs2 = snd_soc_read(codec, AK4497_05_CONTROL4);
dfs2 &= ~AK4497_DFS2;
+
+ dsdsel0 = snd_soc_read(codec, AK4497_06_DSD1);
+ dsdsel0 &= ~AK4497_DSDSEL0;
+
+ dsdsel1 = snd_soc_read(codec, AK4497_09_DSD2);
+ dsdsel1 &= ~AK4497_DSDSEL1;
+
if (!is_dsd) {
switch (nfs1) {
case 8000:
@@ -539,6 +548,33 @@ static int ak4497_hw_params(struct snd_pcm_substream *substream,
default:
return -EINVAL;
}
+ } else {
+ dsd_bclk = params_rate(params) *
+ params_physical_width(params);
+
+ switch (dsd_bclk) {
+ case 2822400:
+ dsdsel0 |= AK4497_DSDSEL0_2MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_2MHZ;
+ break;
+ case 5644800:
+ dsdsel0 |= AK4497_DSDSEL0_5MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_5MHZ;
+ break;
+ case 11289600:
+ dsdsel0 |= AK4497_DSDSEL0_11MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_11MHZ;
+ break;
+ case 22579200:
+ dsdsel0 |= AK4497_DSDSEL0_22MHZ;
+ dsdsel1 |= AK4497_DSDSEL1_22MHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4497_06_DSD1, dsdsel0);
+ snd_soc_write(codec, AK4497_09_DSD2, dsdsel1);
}
snd_soc_write(codec, AK4497_01_CONTROL2, dfs);
diff --git a/sound/soc/codecs/ak4497.h b/sound/soc/codecs/ak4497.h
index 99bd50666ef2..3ba6762e5ddc 100644
--- a/sound/soc/codecs/ak4497.h
+++ b/sound/soc/codecs/ak4497.h
@@ -74,4 +74,17 @@
#define AK4497_DFS2_48KHZ (0x0 << 1) // 30kHz to 216kHz
#define AK4497_DFS2_384KHZ (0x1 << 1) // 384kHz, 768kHz to 108kHz
+
+#define AK4497_DSDSEL0 0x1
+#define AK4497_DSDSEL0_2MHZ 0x0
+#define AK4497_DSDSEL0_5MHZ 0x1
+#define AK4497_DSDSEL0_11MHZ 0x0
+#define AK4497_DSDSEL0_22MHZ 0x1
+
+#define AK4497_DSDSEL1 0x1
+#define AK4497_DSDSEL1_2MHZ 0x0
+#define AK4497_DSDSEL1_5MHZ 0x0
+#define AK4497_DSDSEL1_11MHZ 0x1
+#define AK4497_DSDSEL1_22MHZ 0x1
+
#endif