aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung/i2s.c
diff options
context:
space:
mode:
authorPadmavathi Venna <padma.v@samsung.com>2013-07-26 09:36:48 -0400
committerMark Brown <broonie@linaro.org>2013-07-26 11:05:33 -0400
commitb60be4aa40cff1ebfffc09f92b9007ac1fa24fb4 (patch)
tree8f7349909d072429f2070b917cedfc0a46d4b8fd /sound/soc/samsung/i2s.c
parent7497185f8c5a3e0dc92765bfc723900b492cd8a4 (diff)
ASoC: Samsung: I2S: Modify driver to give more flexibility
This patch modifies the i2s driver to give flexibility towards register handling. This is a pre requirement for enabling i2s support on Exynos5420. This patch modifies only the required registers as a pre-requirement to support on Exynos5420. Signed-off-by: Padmavathi Venna <padma.v@samsung.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/samsung/i2s.c')
-rw-r--r--sound/soc/samsung/i2s.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 7a1734697434..973735841a05 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -198,7 +198,8 @@ static inline bool is_manager(struct i2s_dai *i2s)
198/* Read RCLK of I2S (in multiples of LRCLK) */ 198/* Read RCLK of I2S (in multiples of LRCLK) */
199static inline unsigned get_rfs(struct i2s_dai *i2s) 199static inline unsigned get_rfs(struct i2s_dai *i2s)
200{ 200{
201 u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; 201 u32 rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT);
202 rfs &= MOD_RCLK_MASK;
202 203
203 switch (rfs) { 204 switch (rfs) {
204 case 3: return 768; 205 case 3: return 768;
@@ -212,21 +213,22 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
212static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) 213static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
213{ 214{
214 u32 mod = readl(i2s->addr + I2SMOD); 215 u32 mod = readl(i2s->addr + I2SMOD);
216 int rfs_shift = MOD_RCLK_SHIFT;
215 217
216 mod &= ~MOD_RCLK_MASK; 218 mod &= ~(MOD_RCLK_MASK << rfs_shift);
217 219
218 switch (rfs) { 220 switch (rfs) {
219 case 768: 221 case 768:
220 mod |= MOD_RCLK_768FS; 222 mod |= (MOD_RCLK_768FS << rfs_shift);
221 break; 223 break;
222 case 512: 224 case 512:
223 mod |= MOD_RCLK_512FS; 225 mod |= (MOD_RCLK_512FS << rfs_shift);
224 break; 226 break;
225 case 384: 227 case 384:
226 mod |= MOD_RCLK_384FS; 228 mod |= (MOD_RCLK_384FS << rfs_shift);
227 break; 229 break;
228 default: 230 default:
229 mod |= MOD_RCLK_256FS; 231 mod |= (MOD_RCLK_256FS << rfs_shift);
230 break; 232 break;
231 } 233 }
232 234
@@ -236,7 +238,8 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
236/* Read Bit-Clock of I2S (in multiples of LRCLK) */ 238/* Read Bit-Clock of I2S (in multiples of LRCLK) */
237static inline unsigned get_bfs(struct i2s_dai *i2s) 239static inline unsigned get_bfs(struct i2s_dai *i2s)
238{ 240{
239 u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; 241 u32 bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT;
242 bfs &= MOD_BCLK_MASK;
240 243
241 switch (bfs) { 244 switch (bfs) {
242 case 3: return 24; 245 case 3: return 24;
@@ -250,21 +253,22 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
250static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) 253static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
251{ 254{
252 u32 mod = readl(i2s->addr + I2SMOD); 255 u32 mod = readl(i2s->addr + I2SMOD);
256 int bfs_shift = MOD_BCLK_SHIFT;
253 257
254 mod &= ~MOD_BCLK_MASK; 258 mod &= ~(MOD_BCLK_MASK << bfs_shift);
255 259
256 switch (bfs) { 260 switch (bfs) {
257 case 48: 261 case 48:
258 mod |= MOD_BCLK_48FS; 262 mod |= (MOD_BCLK_48FS << bfs_shift);
259 break; 263 break;
260 case 32: 264 case 32:
261 mod |= MOD_BCLK_32FS; 265 mod |= (MOD_BCLK_32FS << bfs_shift);
262 break; 266 break;
263 case 24: 267 case 24:
264 mod |= MOD_BCLK_24FS; 268 mod |= (MOD_BCLK_24FS << bfs_shift);
265 break; 269 break;
266 case 16: 270 case 16:
267 mod |= MOD_BCLK_16FS; 271 mod |= (MOD_BCLK_16FS << bfs_shift);
268 break; 272 break;
269 default: 273 default:
270 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); 274 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
@@ -491,20 +495,25 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
491{ 495{
492 struct i2s_dai *i2s = to_info(dai); 496 struct i2s_dai *i2s = to_info(dai);
493 u32 mod = readl(i2s->addr + I2SMOD); 497 u32 mod = readl(i2s->addr + I2SMOD);
498 int lrp_shift = MOD_LRP_SHIFT, sdf_shift = MOD_SDF_SHIFT;
499 int sdf_mask, lrp_rlow;
494 u32 tmp = 0; 500 u32 tmp = 0;
495 501
502 sdf_mask = MOD_SDF_MASK << sdf_shift;
503 lrp_rlow = MOD_LR_RLOW << lrp_shift;
504
496 /* Format is priority */ 505 /* Format is priority */
497 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 506 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
498 case SND_SOC_DAIFMT_RIGHT_J: 507 case SND_SOC_DAIFMT_RIGHT_J:
499 tmp |= MOD_LR_RLOW; 508 tmp |= lrp_rlow;
500 tmp |= MOD_SDF_MSB; 509 tmp |= (MOD_SDF_MSB << sdf_shift);
501 break; 510 break;
502 case SND_SOC_DAIFMT_LEFT_J: 511 case SND_SOC_DAIFMT_LEFT_J:
503 tmp |= MOD_LR_RLOW; 512 tmp |= lrp_rlow;
504 tmp |= MOD_SDF_LSB; 513 tmp |= (MOD_SDF_LSB << sdf_shift);
505 break; 514 break;
506 case SND_SOC_DAIFMT_I2S: 515 case SND_SOC_DAIFMT_I2S:
507 tmp |= MOD_SDF_IIS; 516 tmp |= (MOD_SDF_IIS << sdf_shift);
508 break; 517 break;
509 default: 518 default:
510 dev_err(&i2s->pdev->dev, "Format not supported\n"); 519 dev_err(&i2s->pdev->dev, "Format not supported\n");
@@ -519,10 +528,10 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
519 case SND_SOC_DAIFMT_NB_NF: 528 case SND_SOC_DAIFMT_NB_NF:
520 break; 529 break;
521 case SND_SOC_DAIFMT_NB_IF: 530 case SND_SOC_DAIFMT_NB_IF:
522 if (tmp & MOD_LR_RLOW) 531 if (tmp & lrp_rlow)
523 tmp &= ~MOD_LR_RLOW; 532 tmp &= ~lrp_rlow;
524 else 533 else
525 tmp |= MOD_LR_RLOW; 534 tmp |= lrp_rlow;
526 break; 535 break;
527 default: 536 default:
528 dev_err(&i2s->pdev->dev, "Polarity not supported\n"); 537 dev_err(&i2s->pdev->dev, "Polarity not supported\n");
@@ -544,15 +553,18 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
544 return -EINVAL; 553 return -EINVAL;
545 } 554 }
546 555
556 /*
557 * Don't change the I2S mode if any controller is active on this
558 * channel.
559 */
547 if (any_active(i2s) && 560 if (any_active(i2s) &&
548 ((mod & (MOD_SDF_MASK | MOD_LR_RLOW 561 ((mod & (sdf_mask | lrp_rlow | MOD_SLAVE)) != tmp)) {
549 | MOD_SLAVE)) != tmp)) {
550 dev_err(&i2s->pdev->dev, 562 dev_err(&i2s->pdev->dev,
551 "%s:%d Other DAI busy\n", __func__, __LINE__); 563 "%s:%d Other DAI busy\n", __func__, __LINE__);
552 return -EAGAIN; 564 return -EAGAIN;
553 } 565 }
554 566
555 mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); 567 mod &= ~(sdf_mask | lrp_rlow | MOD_SLAVE);
556 mod |= tmp; 568 mod |= tmp;
557 writel(mod, i2s->addr + I2SMOD); 569 writel(mod, i2s->addr + I2SMOD);
558 570