1 /* 2 * linux/sound/soc/ep93xx-i2s.c 3 * EP93xx I2S driver 4 * 5 * Copyright (C) 2010 Ryan Mallon 6 * 7 * Based on the original driver by: 8 * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail> 9 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 */ 16 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include <linux/slab.h> 20 #include <linux/clk.h> 21 #include <linux/io.h> 22 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/initval.h> 27 #include <sound/soc.h> 28 29 #include <mach/hardware.h> 30 #include <mach/ep93xx-regs.h> 31 #include <linux/platform_data/dma-ep93xx.h> 32 33 #define EP93XX_I2S_TXCLKCFG 0x00 34 #define EP93XX_I2S_RXCLKCFG 0x04 35 #define EP93XX_I2S_GLCTRL 0x0C 36 37 #define EP93XX_I2S_TXLINCTRLDATA 0x28 38 #define EP93XX_I2S_TXCTRL 0x2C 39 #define EP93XX_I2S_TXWRDLEN 0x30 40 #define EP93XX_I2S_TX0EN 0x34 41 42 #define EP93XX_I2S_RXLINCTRLDATA 0x58 43 #define EP93XX_I2S_RXCTRL 0x5C 44 #define EP93XX_I2S_RXWRDLEN 0x60 45 #define EP93XX_I2S_RX0EN 0x64 46 47 #define EP93XX_I2S_WRDLEN_16 (0 << 0) 48 #define EP93XX_I2S_WRDLEN_24 (1 << 0) 49 #define EP93XX_I2S_WRDLEN_32 (2 << 0) 50 51 #define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */ 52 53 #define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */ 54 #define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */ 55 #define EP93XX_I2S_CLKCFG_REL (1 << 2) /* First bit transition */ 56 #define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */ 57 #define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */ 58 59 struct ep93xx_i2s_info { 60 struct clk *mclk; 61 struct clk *sclk; 62 struct clk *lrclk; 63 void __iomem *regs; 64 }; 65 66 static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { 67 [SNDRV_PCM_STREAM_PLAYBACK] = { 68 .name = "i2s-pcm-out", 69 .port = EP93XX_DMA_I2S1, 70 .direction = DMA_MEM_TO_DEV, 71 }, 72 [SNDRV_PCM_STREAM_CAPTURE] = { 73 .name = "i2s-pcm-in", 74 .port = EP93XX_DMA_I2S1, 75 .direction = DMA_DEV_TO_MEM, 76 }, 77 }; 78 79 static inline void ep93xx_i2s_write_reg(struct ep93xx_i2s_info *info, 80 unsigned reg, unsigned val) 81 { 82 __raw_writel(val, info->regs + reg); 83 } 84 85 static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info, 86 unsigned reg) 87 { 88 return __raw_readl(info->regs + reg); 89 } 90 91 static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream) 92 { 93 unsigned base_reg; 94 int i; 95 96 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 && 97 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) { 98 /* Enable clocks */ 99 clk_enable(info->mclk); 100 clk_enable(info->sclk); 101 clk_enable(info->lrclk); 102 103 /* Enable i2s */ 104 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1); 105 } 106 107 /* Enable fifos */ 108 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 109 base_reg = EP93XX_I2S_TX0EN; 110 else 111 base_reg = EP93XX_I2S_RX0EN; 112 for (i = 0; i < 3; i++) 113 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 1); 114 } 115 116 static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) 117 { 118 unsigned base_reg; 119 int i; 120 121 /* Disable fifos */ 122 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 123 base_reg = EP93XX_I2S_TX0EN; 124 else 125 base_reg = EP93XX_I2S_RX0EN; 126 for (i = 0; i < 3; i++) 127 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 0); 128 129 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 && 130 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) { 131 /* Disable i2s */ 132 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0); 133 134 /* Disable clocks */ 135 clk_disable(info->lrclk); 136 clk_disable(info->sclk); 137 clk_disable(info->mclk); 138 } 139 } 140 141 static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) 142 { 143 dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK]; 144 dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; 145 146 return 0; 147 } 148 149 static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream, 150 struct snd_soc_dai *dai) 151 { 152 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 153 154 ep93xx_i2s_disable(info, substream->stream); 155 } 156 157 static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 158 unsigned int fmt) 159 { 160 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai); 161 unsigned int clk_cfg, lin_ctrl; 162 163 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG); 164 lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA); 165 166 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 167 case SND_SOC_DAIFMT_I2S: 168 clk_cfg |= EP93XX_I2S_CLKCFG_REL; 169 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST; 170 break; 171 172 case SND_SOC_DAIFMT_LEFT_J: 173 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 174 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST; 175 break; 176 177 case SND_SOC_DAIFMT_RIGHT_J: 178 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 179 lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST; 180 break; 181 182 default: 183 return -EINVAL; 184 } 185 186 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 187 case SND_SOC_DAIFMT_CBS_CFS: 188 /* CPU is master */ 189 clk_cfg |= EP93XX_I2S_CLKCFG_MASTER; 190 break; 191 192 case SND_SOC_DAIFMT_CBM_CFM: 193 /* Codec is master */ 194 clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER; 195 break; 196 197 default: 198 return -EINVAL; 199 } 200 201 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 202 case SND_SOC_DAIFMT_NB_NF: 203 /* Negative bit clock, lrclk low on left word */ 204 clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL); 205 break; 206 207 case SND_SOC_DAIFMT_NB_IF: 208 /* Negative bit clock, lrclk low on right word */ 209 clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP; 210 clk_cfg |= EP93XX_I2S_CLKCFG_REL; 211 break; 212 213 case SND_SOC_DAIFMT_IB_NF: 214 /* Positive bit clock, lrclk low on left word */ 215 clk_cfg |= EP93XX_I2S_CLKCFG_CKP; 216 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 217 break; 218 219 case SND_SOC_DAIFMT_IB_IF: 220 /* Positive bit clock, lrclk low on right word */ 221 clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL; 222 break; 223 } 224 225 /* Write new register values */ 226 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg); 227 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg); 228 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl); 229 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl); 230 return 0; 231 } 232 233 static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream, 234 struct snd_pcm_hw_params *params, 235 struct snd_soc_dai *dai) 236 { 237 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 238 unsigned word_len, div, sdiv, lrdiv; 239 int err; 240 241 switch (params_format(params)) { 242 case SNDRV_PCM_FORMAT_S16_LE: 243 word_len = EP93XX_I2S_WRDLEN_16; 244 break; 245 246 case SNDRV_PCM_FORMAT_S24_LE: 247 word_len = EP93XX_I2S_WRDLEN_24; 248 break; 249 250 case SNDRV_PCM_FORMAT_S32_LE: 251 word_len = EP93XX_I2S_WRDLEN_32; 252 break; 253 254 default: 255 return -EINVAL; 256 } 257 258 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 259 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXWRDLEN, word_len); 260 else 261 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len); 262 263 /* 264 * EP93xx I2S module can be setup so SCLK / LRCLK value can be 265 * 32, 64, 128. MCLK / SCLK value can be 2 and 4. 266 * We set LRCLK equal to `rate' and minimum SCLK / LRCLK 267 * value is 64, because our sample size is 32 bit * 2 channels. 268 * I2S standard permits us to transmit more bits than 269 * the codec uses. 270 */ 271 div = clk_get_rate(info->mclk) / params_rate(params); 272 sdiv = 4; 273 if (div > (256 + 512) / 2) { 274 lrdiv = 128; 275 } else { 276 lrdiv = 64; 277 if (div < (128 + 256) / 2) 278 sdiv = 2; 279 } 280 281 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv); 282 if (err) 283 return err; 284 285 err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv); 286 if (err) 287 return err; 288 289 ep93xx_i2s_enable(info, substream->stream); 290 return 0; 291 } 292 293 static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, 294 unsigned int freq, int dir) 295 { 296 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai); 297 298 if (dir == SND_SOC_CLOCK_IN || clk_id != 0) 299 return -EINVAL; 300 301 return clk_set_rate(info->mclk, freq); 302 } 303 304 #ifdef CONFIG_PM 305 static int ep93xx_i2s_suspend(struct snd_soc_dai *dai) 306 { 307 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 308 309 if (!dai->active) 310 return 0; 311 312 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK); 313 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE); 314 315 return 0; 316 } 317 318 static int ep93xx_i2s_resume(struct snd_soc_dai *dai) 319 { 320 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 321 322 if (!dai->active) 323 return 0; 324 325 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK); 326 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE); 327 328 return 0; 329 } 330 #else 331 #define ep93xx_i2s_suspend NULL 332 #define ep93xx_i2s_resume NULL 333 #endif 334 335 static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { 336 .shutdown = ep93xx_i2s_shutdown, 337 .hw_params = ep93xx_i2s_hw_params, 338 .set_sysclk = ep93xx_i2s_set_sysclk, 339 .set_fmt = ep93xx_i2s_set_dai_fmt, 340 }; 341 342 #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 343 344 static struct snd_soc_dai_driver ep93xx_i2s_dai = { 345 .symmetric_rates= 1, 346 .probe = ep93xx_i2s_dai_probe, 347 .suspend = ep93xx_i2s_suspend, 348 .resume = ep93xx_i2s_resume, 349 .playback = { 350 .channels_min = 2, 351 .channels_max = 2, 352 .rates = SNDRV_PCM_RATE_8000_192000, 353 .formats = EP93XX_I2S_FORMATS, 354 }, 355 .capture = { 356 .channels_min = 2, 357 .channels_max = 2, 358 .rates = SNDRV_PCM_RATE_8000_192000, 359 .formats = EP93XX_I2S_FORMATS, 360 }, 361 .ops = &ep93xx_i2s_dai_ops, 362 }; 363 364 static const struct snd_soc_component_driver ep93xx_i2s_component = { 365 .name = "ep93xx-i2s", 366 }; 367 368 static int ep93xx_i2s_probe(struct platform_device *pdev) 369 { 370 struct ep93xx_i2s_info *info; 371 struct resource *res; 372 int err; 373 374 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 375 if (!info) 376 return -ENOMEM; 377 378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 379 info->regs = devm_ioremap_resource(&pdev->dev, res); 380 if (IS_ERR(info->regs)) 381 return PTR_ERR(info->regs); 382 383 info->mclk = clk_get(&pdev->dev, "mclk"); 384 if (IS_ERR(info->mclk)) { 385 err = PTR_ERR(info->mclk); 386 goto fail; 387 } 388 389 info->sclk = clk_get(&pdev->dev, "sclk"); 390 if (IS_ERR(info->sclk)) { 391 err = PTR_ERR(info->sclk); 392 goto fail_put_mclk; 393 } 394 395 info->lrclk = clk_get(&pdev->dev, "lrclk"); 396 if (IS_ERR(info->lrclk)) { 397 err = PTR_ERR(info->lrclk); 398 goto fail_put_sclk; 399 } 400 401 dev_set_drvdata(&pdev->dev, info); 402 403 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, 404 &ep93xx_i2s_dai, 1); 405 if (err) 406 goto fail_put_lrclk; 407 408 return 0; 409 410 fail_put_lrclk: 411 clk_put(info->lrclk); 412 fail_put_sclk: 413 clk_put(info->sclk); 414 fail_put_mclk: 415 clk_put(info->mclk); 416 fail: 417 return err; 418 } 419 420 static int ep93xx_i2s_remove(struct platform_device *pdev) 421 { 422 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 423 424 snd_soc_unregister_component(&pdev->dev); 425 clk_put(info->lrclk); 426 clk_put(info->sclk); 427 clk_put(info->mclk); 428 return 0; 429 } 430 431 static struct platform_driver ep93xx_i2s_driver = { 432 .probe = ep93xx_i2s_probe, 433 .remove = ep93xx_i2s_remove, 434 .driver = { 435 .name = "ep93xx-i2s", 436 .owner = THIS_MODULE, 437 }, 438 }; 439 440 module_platform_driver(ep93xx_i2s_driver); 441 442 MODULE_ALIAS("platform:ep93xx-i2s"); 443 MODULE_AUTHOR("Ryan Mallon"); 444 MODULE_DESCRIPTION("EP93XX I2S driver"); 445 MODULE_LICENSE("GPL"); 446