summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorViorel Suman <viorel.suman@nxp.com>2018-12-04 17:03:08 +0200
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:35:36 +0800
commit5a38926f0ef261b4d6f9df4a704d9c5974ae3639 (patch)
treee47f00d433f92d919dcfe0cbdfb8c585521515cc /sound
parentbd89e55af41e722c7c7d58a44ce0b699e734d346 (diff)
MLK-17817-1: ASoC: ak4458: enable daisy chain
Enable Daisy Chain if in TDM mode and the number of played channels is bigger than the maximum supported number of channels. Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ak4458.c50
-rw-r--r--sound/soc/codecs/ak4458.h2
2 files changed, 32 insertions, 20 deletions
diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index 9464cca52258..6cb4aa28ef65 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -616,6 +616,20 @@ static const struct snd_soc_dapm_route ak4458_intercon[] = {
};
+static int ak4458_get_tdm_mode(struct ak4458_priv *ak4458)
+{
+ switch(ak4458->slots * ak4458->slot_width) {
+ case 128:
+ return 1;
+ case 256:
+ return 2;
+ case 512:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
static int ak4458_rstn_control(struct snd_soc_codec *codec, int bit)
{
u8 rstn;
@@ -637,11 +651,14 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
- u8 format, dsdsel0, dsdsel1;
+ u8 format, dsdsel0, dsdsel1, dchn;
int pcm_width = max(params_physical_width(params), ak4458->slot_width);
- int ret, dsd_bclk;
+ int ret, dsd_bclk, channels, channels_max;
bool is_dsd = false;
+ channels = params_channels(params);
+ channels_max = dai->driver->playback.channels_max;
+
#ifdef AK4458_ACKS_USE_MANUAL_MODE
u8 dfs1, dfs2;
#endif
@@ -778,6 +795,16 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
snd_soc_write(codec, AK4458_00_CONTROL1, format);
+ /**
+ * Enable/disable Daisy Chain if in TDM mode and the number of played
+ * channels is bigger than the maximum supported number of channels
+ */
+ dchn = ak4458_get_tdm_mode(ak4458) &&
+ (ak4458->fmt == SND_SOC_DAIFMT_DSP_B) &&
+ (channels > channels_max ) ? AK4458_DCHAIN_MASK : 0;
+
+ snd_soc_update_bits(codec, AK4458_0B_CONTROL7, AK4458_DCHAIN_MASK, dchn);
+
ret = ak4458_rstn_control(codec, 0);
if (ret)
return ret;
@@ -934,33 +961,16 @@ static int ak4458_set_dai_mute(struct snd_soc_dai *dai, int mute)
static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int slot_width)
{
-
struct snd_soc_codec *codec = dai->codec;
struct ak4458_priv *ak4458 = snd_soc_codec_get_drvdata(codec);
- int tdm_mode = 0;
int reg;
ak4458->slots = slots;
ak4458->slot_width = slot_width;
- switch(slots * slot_width) {
- case 128:
- tdm_mode = 1;
- break;
- case 256:
- tdm_mode = 2;
- break;
- case 512:
- tdm_mode = 3;
- break;
- default:
- tdm_mode = 0;
- break;
- }
-
reg = snd_soc_read(codec, AK4458_0A_CONTROL6);
reg &= ~(0x3 << 6);
- reg |= tdm_mode << 6;
+ reg |= ak4458_get_tdm_mode(ak4458) << 6;
snd_soc_write(codec, AK4458_0A_CONTROL6, reg);
return 0;
diff --git a/sound/soc/codecs/ak4458.h b/sound/soc/codecs/ak4458.h
index 22c00a384dbc..7a83c2e236f1 100644
--- a/sound/soc/codecs/ak4458.h
+++ b/sound/soc/codecs/ak4458.h
@@ -123,6 +123,8 @@
#define AK4458_DSDSEL_MASK (0x1 << 0)
#define AK4458_DP_MASK (0x1 << 7)
+#define AK4458_DCHAIN_MASK (0x1 << 1)
+
extern const struct regmap_config ak4458_i2c_regmap_config;
extern const struct regmap_config ak4458_spi_regmap_config;
extern const struct dev_pm_ops ak4458_pm;