diff options
author | Padmavathi Venna <padma.v@samsung.com> | 2013-07-26 09:36:48 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-26 11:05:33 -0400 |
commit | b60be4aa40cff1ebfffc09f92b9007ac1fa24fb4 (patch) | |
tree | 8f7349909d072429f2070b917cedfc0a46d4b8fd /sound/soc/samsung/i2s.c | |
parent | 7497185f8c5a3e0dc92765bfc723900b492cd8a4 (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.c | 58 |
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) */ |
199 | static inline unsigned get_rfs(struct i2s_dai *i2s) | 199 | static 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) | |||
212 | static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) | 213 | static 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) */ |
237 | static inline unsigned get_bfs(struct i2s_dai *i2s) | 239 | static 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) | |||
250 | static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) | 253 | static 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 | ||