aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2017-11-08 17:42:31 -0500
committerMark Brown <broonie@kernel.org>2017-11-09 06:42:26 -0500
commite0d746cc0155a51cc24eb56286cd21a2c5aa4985 (patch)
tree483e905cc201fec43356a82fc939c6787ea64cc6
parent2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (diff)
ASoC: da7213: add support for DSP modes
DSP modes are documented in the data sheet but not enabled in the driver. The work-around already implemented for DA7218/9 is also required to make sure the bit clock handling in DSP modes follows ASoC conventions. Tested with ARD-AUDIO-DA7212 and Minnowmax Turbot boards Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Acked-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/da7213.c58
-rw-r--r--sound/soc/codecs/da7213.h1
2 files changed, 49 insertions, 10 deletions
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index cc0b2d2eaf15..41d9b1da27c2 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1220,6 +1220,7 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1220 struct snd_soc_codec *codec = codec_dai->codec; 1220 struct snd_soc_codec *codec = codec_dai->codec;
1221 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 1221 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1222 u8 dai_clk_mode = 0, dai_ctrl = 0; 1222 u8 dai_clk_mode = 0, dai_ctrl = 0;
1223 u8 dai_offset = 0;
1223 1224
1224 /* Set master/slave mode */ 1225 /* Set master/slave mode */
1225 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1226 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1234,17 +1235,46 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1234 } 1235 }
1235 1236
1236 /* Set clock normal/inverted */ 1237 /* Set clock normal/inverted */
1237 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1238 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1238 case SND_SOC_DAIFMT_NB_NF: 1239 case SND_SOC_DAIFMT_I2S:
1239 break; 1240 case SND_SOC_DAIFMT_LEFT_J:
1240 case SND_SOC_DAIFMT_NB_IF: 1241 case SND_SOC_DAIFMT_RIGHT_J:
1241 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV; 1242 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1242 break; 1243 case SND_SOC_DAIFMT_NB_NF:
1243 case SND_SOC_DAIFMT_IB_NF: 1244 break;
1244 dai_clk_mode |= DA7213_DAI_CLK_POL_INV; 1245 case SND_SOC_DAIFMT_NB_IF:
1246 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV;
1247 break;
1248 case SND_SOC_DAIFMT_IB_NF:
1249 dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
1250 break;
1251 case SND_SOC_DAIFMT_IB_IF:
1252 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV |
1253 DA7213_DAI_CLK_POL_INV;
1254 break;
1255 default:
1256 return -EINVAL;
1257 }
1245 break; 1258 break;
1246 case SND_SOC_DAIFMT_IB_IF: 1259 case SND_SOC_DAI_FORMAT_DSP_A:
1247 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV | DA7213_DAI_CLK_POL_INV; 1260 case SND_SOC_DAI_FORMAT_DSP_B:
1261 /* The bclk is inverted wrt ASoC conventions */
1262 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1263 case SND_SOC_DAIFMT_NB_NF:
1264 dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
1265 break;
1266 case SND_SOC_DAIFMT_NB_IF:
1267 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV |
1268 DA7213_DAI_CLK_POL_INV;
1269 break;
1270 case SND_SOC_DAIFMT_IB_NF:
1271 break;
1272 case SND_SOC_DAIFMT_IB_IF:
1273 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV;
1274 break;
1275 default:
1276 return -EINVAL;
1277 }
1248 break; 1278 break;
1249 default: 1279 default:
1250 return -EINVAL; 1280 return -EINVAL;
@@ -1261,6 +1291,13 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1261 case SND_SOC_DAIFMT_RIGHT_J: 1291 case SND_SOC_DAIFMT_RIGHT_J:
1262 dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J; 1292 dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
1263 break; 1293 break;
1294 case SND_SOC_DAI_FORMAT_DSP_A: /* L data MSB after FRM LRC */
1295 dai_ctrl |= DA7213_DAI_FORMAT_DSP;
1296 dai_offset = 1;
1297 break;
1298 case SND_SOC_DAI_FORMAT_DSP_B: /* L data MSB during FRM LRC */
1299 dai_ctrl |= DA7213_DAI_FORMAT_DSP;
1300 break;
1264 default: 1301 default:
1265 return -EINVAL; 1302 return -EINVAL;
1266 } 1303 }
@@ -1271,6 +1308,7 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1271 snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode); 1308 snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
1272 snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK, 1309 snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
1273 dai_ctrl); 1310 dai_ctrl);
1311 snd_soc_write(codec, DA7213_DAI_OFFSET, dai_offset);
1274 1312
1275 return 0; 1313 return 0;
1276} 1314}
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 16ef56f77cd4..5a78dba1dcb5 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -188,6 +188,7 @@
188#define DA7213_DAI_FORMAT_I2S_MODE (0x0 << 0) 188#define DA7213_DAI_FORMAT_I2S_MODE (0x0 << 0)
189#define DA7213_DAI_FORMAT_LEFT_J (0x1 << 0) 189#define DA7213_DAI_FORMAT_LEFT_J (0x1 << 0)
190#define DA7213_DAI_FORMAT_RIGHT_J (0x2 << 0) 190#define DA7213_DAI_FORMAT_RIGHT_J (0x2 << 0)
191#define DA7213_DAI_FORMAT_DSP (0x3 << 0)
191#define DA7213_DAI_FORMAT_MASK (0x3 << 0) 192#define DA7213_DAI_FORMAT_MASK (0x3 << 0)
192#define DA7213_DAI_WORD_LENGTH_S16_LE (0x0 << 2) 193#define DA7213_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
193#define DA7213_DAI_WORD_LENGTH_S20_LE (0x1 << 2) 194#define DA7213_DAI_WORD_LENGTH_S20_LE (0x1 << 2)