1 /* 2 * Copyright (C) 2015 Andrea Venturi 3 * Andrea Venturi <be17068@iperbole.bo.it> 4 * 5 * Copyright (C) 2016 Maxime Ripard 6 * Maxime Ripard <maxime.ripard@free-electrons.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 */ 13 14 #include <linux/clk.h> 15 #include <linux/dmaengine.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/regmap.h> 20 21 #include <sound/dmaengine_pcm.h> 22 #include <sound/pcm_params.h> 23 #include <sound/soc.h> 24 #include <sound/soc-dai.h> 25 26 #define SUN4I_I2S_CTRL_REG 0x00 27 #define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8) 28 #define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo)) 29 #define SUN4I_I2S_CTRL_MODE_MASK BIT(5) 30 #define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5) 31 #define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5) 32 #define SUN4I_I2S_CTRL_TX_EN BIT(2) 33 #define SUN4I_I2S_CTRL_RX_EN BIT(1) 34 #define SUN4I_I2S_CTRL_GL_EN BIT(0) 35 36 #define SUN4I_I2S_FMT0_REG 0x04 37 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(7) 38 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 7) 39 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 7) 40 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK BIT(6) 41 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 6) 42 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 6) 43 #define SUN4I_I2S_FMT0_SR_MASK GENMASK(5, 4) 44 #define SUN4I_I2S_FMT0_SR(sr) ((sr) << 4) 45 #define SUN4I_I2S_FMT0_WSS_MASK GENMASK(3, 2) 46 #define SUN4I_I2S_FMT0_WSS(wss) ((wss) << 2) 47 #define SUN4I_I2S_FMT0_FMT_MASK GENMASK(1, 0) 48 #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0) 49 #define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0) 50 #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) 51 52 #define SUN4I_I2S_FMT1_REG 0x08 53 #define SUN4I_I2S_FIFO_TX_REG 0x0c 54 #define SUN4I_I2S_FIFO_RX_REG 0x10 55 56 #define SUN4I_I2S_FIFO_CTRL_REG 0x14 57 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX BIT(25) 58 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX BIT(24) 59 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK BIT(2) 60 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode) ((mode) << 2) 61 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK GENMASK(1, 0) 62 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode) (mode) 63 64 #define SUN4I_I2S_FIFO_STA_REG 0x18 65 66 #define SUN4I_I2S_DMA_INT_CTRL_REG 0x1c 67 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN BIT(7) 68 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN BIT(3) 69 70 #define SUN4I_I2S_INT_STA_REG 0x20 71 72 #define SUN4I_I2S_CLK_DIV_REG 0x24 73 #define SUN4I_I2S_CLK_DIV_MCLK_EN BIT(7) 74 #define SUN4I_I2S_CLK_DIV_BCLK_MASK GENMASK(6, 4) 75 #define SUN4I_I2S_CLK_DIV_BCLK(bclk) ((bclk) << 4) 76 #define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0) 77 #define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0) 78 79 #define SUN4I_I2S_RX_CNT_REG 0x28 80 #define SUN4I_I2S_TX_CNT_REG 0x2c 81 82 #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 83 #define SUN4I_I2S_TX_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) 84 85 #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 86 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2)) 87 88 #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38 89 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c 90 91 struct sun4i_i2s { 92 struct clk *bus_clk; 93 struct clk *mod_clk; 94 struct regmap *regmap; 95 96 struct snd_dmaengine_dai_dma_data playback_dma_data; 97 }; 98 99 struct sun4i_i2s_clk_div { 100 u8 div; 101 u8 val; 102 }; 103 104 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = { 105 { .div = 2, .val = 0 }, 106 { .div = 4, .val = 1 }, 107 { .div = 6, .val = 2 }, 108 { .div = 8, .val = 3 }, 109 { .div = 12, .val = 4 }, 110 { .div = 16, .val = 5 }, 111 }; 112 113 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { 114 { .div = 1, .val = 0 }, 115 { .div = 2, .val = 1 }, 116 { .div = 4, .val = 2 }, 117 { .div = 6, .val = 3 }, 118 { .div = 8, .val = 4 }, 119 { .div = 12, .val = 5 }, 120 { .div = 16, .val = 6 }, 121 { .div = 24, .val = 7 }, 122 }; 123 124 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, 125 unsigned int oversample_rate, 126 unsigned int word_size) 127 { 128 int div = oversample_rate / word_size / 2; 129 int i; 130 131 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) { 132 const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i]; 133 134 if (bdiv->div == div) 135 return bdiv->val; 136 } 137 138 return -EINVAL; 139 } 140 141 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s, 142 unsigned int oversample_rate, 143 unsigned int module_rate, 144 unsigned int sampling_rate) 145 { 146 int div = module_rate / sampling_rate / oversample_rate; 147 int i; 148 149 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) { 150 const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i]; 151 152 if (mdiv->div == div) 153 return mdiv->val; 154 } 155 156 return -EINVAL; 157 } 158 159 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 }; 160 161 static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, 162 unsigned int rate, 163 unsigned int word_size) 164 { 165 unsigned int clk_rate; 166 int bclk_div, mclk_div; 167 int ret, i; 168 169 switch (rate) { 170 case 176400: 171 case 88200: 172 case 44100: 173 case 22050: 174 case 11025: 175 clk_rate = 22579200; 176 break; 177 178 case 192000: 179 case 128000: 180 case 96000: 181 case 64000: 182 case 48000: 183 case 32000: 184 case 24000: 185 case 16000: 186 case 12000: 187 case 8000: 188 clk_rate = 24576000; 189 break; 190 191 default: 192 return -EINVAL; 193 } 194 195 ret = clk_set_rate(i2s->mod_clk, clk_rate); 196 if (ret) 197 return ret; 198 199 /* Always favor the highest oversampling rate */ 200 for (i = (ARRAY_SIZE(sun4i_i2s_oversample_rates) - 1); i >= 0; i--) { 201 unsigned int oversample_rate = sun4i_i2s_oversample_rates[i]; 202 203 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, 204 word_size); 205 mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, 206 clk_rate, 207 rate); 208 209 if ((bclk_div >= 0) && (mclk_div >= 0)) 210 break; 211 } 212 213 if ((bclk_div < 0) || (mclk_div < 0)) 214 return -EINVAL; 215 216 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, 217 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | 218 SUN4I_I2S_CLK_DIV_MCLK(mclk_div) | 219 SUN4I_I2S_CLK_DIV_MCLK_EN); 220 221 return 0; 222 } 223 224 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, 225 struct snd_pcm_hw_params *params, 226 struct snd_soc_dai *dai) 227 { 228 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 229 int sr, wss; 230 u32 width; 231 232 if (params_channels(params) != 2) 233 return -EINVAL; 234 235 switch (params_physical_width(params)) { 236 case 16: 237 width = DMA_SLAVE_BUSWIDTH_2_BYTES; 238 break; 239 default: 240 return -EINVAL; 241 } 242 i2s->playback_dma_data.addr_width = width; 243 244 switch (params_width(params)) { 245 case 16: 246 sr = 0; 247 wss = 0; 248 break; 249 250 default: 251 return -EINVAL; 252 } 253 254 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, 255 SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK, 256 SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr)); 257 258 return sun4i_i2s_set_clk_rate(i2s, params_rate(params), 259 params_width(params)); 260 } 261 262 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 263 { 264 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 265 u32 val; 266 267 /* DAI Mode */ 268 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 269 case SND_SOC_DAIFMT_I2S: 270 val = SUN4I_I2S_FMT0_FMT_I2S; 271 break; 272 case SND_SOC_DAIFMT_LEFT_J: 273 val = SUN4I_I2S_FMT0_FMT_LEFT_J; 274 break; 275 case SND_SOC_DAIFMT_RIGHT_J: 276 val = SUN4I_I2S_FMT0_FMT_RIGHT_J; 277 break; 278 default: 279 return -EINVAL; 280 } 281 282 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, 283 SUN4I_I2S_FMT0_FMT_MASK, 284 val); 285 286 /* DAI clock polarity */ 287 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 288 case SND_SOC_DAIFMT_IB_IF: 289 /* Invert both clocks */ 290 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | 291 SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED; 292 break; 293 case SND_SOC_DAIFMT_IB_NF: 294 /* Invert bit clock */ 295 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | 296 SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; 297 break; 298 case SND_SOC_DAIFMT_NB_IF: 299 /* Invert frame clock */ 300 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED | 301 SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL; 302 break; 303 case SND_SOC_DAIFMT_NB_NF: 304 /* Nothing to do for both normal cases */ 305 val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL | 306 SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; 307 break; 308 default: 309 return -EINVAL; 310 } 311 312 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, 313 SUN4I_I2S_FMT0_BCLK_POLARITY_MASK | 314 SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK, 315 val); 316 317 /* DAI clock master masks */ 318 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 319 case SND_SOC_DAIFMT_CBS_CFS: 320 /* BCLK and LRCLK master */ 321 val = SUN4I_I2S_CTRL_MODE_MASTER; 322 break; 323 case SND_SOC_DAIFMT_CBM_CFM: 324 /* BCLK and LRCLK slave */ 325 val = SUN4I_I2S_CTRL_MODE_SLAVE; 326 break; 327 default: 328 return -EINVAL; 329 } 330 331 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 332 SUN4I_I2S_CTRL_MODE_MASK, 333 val); 334 335 /* Set significant bits in our FIFOs */ 336 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, 337 SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK | 338 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK, 339 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) | 340 SUN4I_I2S_FIFO_CTRL_RX_MODE(1)); 341 return 0; 342 } 343 344 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s) 345 { 346 /* Flush TX FIFO */ 347 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, 348 SUN4I_I2S_FIFO_CTRL_FLUSH_TX, 349 SUN4I_I2S_FIFO_CTRL_FLUSH_TX); 350 351 /* Clear TX counter */ 352 regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0); 353 354 /* Enable TX Block */ 355 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 356 SUN4I_I2S_CTRL_TX_EN, 357 SUN4I_I2S_CTRL_TX_EN); 358 359 /* Enable TX DRQ */ 360 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 361 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN, 362 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN); 363 } 364 365 366 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s) 367 { 368 /* Disable TX Block */ 369 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 370 SUN4I_I2S_CTRL_TX_EN, 371 0); 372 373 /* Disable TX DRQ */ 374 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 375 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN, 376 0); 377 } 378 379 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 380 struct snd_soc_dai *dai) 381 { 382 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 383 384 switch (cmd) { 385 case SNDRV_PCM_TRIGGER_START: 386 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 387 case SNDRV_PCM_TRIGGER_RESUME: 388 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 389 sun4i_i2s_start_playback(i2s); 390 else 391 return -EINVAL; 392 break; 393 394 case SNDRV_PCM_TRIGGER_STOP: 395 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 396 case SNDRV_PCM_TRIGGER_SUSPEND: 397 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 398 sun4i_i2s_stop_playback(i2s); 399 else 400 return -EINVAL; 401 break; 402 403 default: 404 return -EINVAL; 405 } 406 407 return 0; 408 } 409 410 static int sun4i_i2s_startup(struct snd_pcm_substream *substream, 411 struct snd_soc_dai *dai) 412 { 413 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 414 415 /* Enable the whole hardware block */ 416 regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 417 SUN4I_I2S_CTRL_GL_EN); 418 419 /* Enable the first output line */ 420 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 421 SUN4I_I2S_CTRL_SDO_EN_MASK, 422 SUN4I_I2S_CTRL_SDO_EN(0)); 423 424 /* Enable the first two channels */ 425 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG, 426 SUN4I_I2S_TX_CHAN_SEL(2)); 427 428 /* Map them to the two first samples coming in */ 429 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 430 SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1)); 431 432 return clk_prepare_enable(i2s->mod_clk); 433 } 434 435 static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream, 436 struct snd_soc_dai *dai) 437 { 438 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 439 440 clk_disable_unprepare(i2s->mod_clk); 441 442 /* Disable our output lines */ 443 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 444 SUN4I_I2S_CTRL_SDO_EN_MASK, 0); 445 446 /* Disable the whole hardware block */ 447 regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0); 448 } 449 450 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { 451 .hw_params = sun4i_i2s_hw_params, 452 .set_fmt = sun4i_i2s_set_fmt, 453 .shutdown = sun4i_i2s_shutdown, 454 .startup = sun4i_i2s_startup, 455 .trigger = sun4i_i2s_trigger, 456 }; 457 458 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai) 459 { 460 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 461 462 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, NULL); 463 464 snd_soc_dai_set_drvdata(dai, i2s); 465 466 return 0; 467 } 468 469 static struct snd_soc_dai_driver sun4i_i2s_dai = { 470 .probe = sun4i_i2s_dai_probe, 471 .playback = { 472 .stream_name = "Playback", 473 .channels_min = 2, 474 .channels_max = 2, 475 .rates = SNDRV_PCM_RATE_8000_192000, 476 .formats = SNDRV_PCM_FMTBIT_S16_LE, 477 }, 478 .ops = &sun4i_i2s_dai_ops, 479 .symmetric_rates = 1, 480 }; 481 482 static const struct snd_soc_component_driver sun4i_i2s_component = { 483 .name = "sun4i-dai", 484 }; 485 486 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg) 487 { 488 switch (reg) { 489 case SUN4I_I2S_FIFO_TX_REG: 490 return false; 491 492 default: 493 return true; 494 } 495 } 496 497 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg) 498 { 499 switch (reg) { 500 case SUN4I_I2S_FIFO_RX_REG: 501 case SUN4I_I2S_FIFO_STA_REG: 502 return false; 503 504 default: 505 return true; 506 } 507 } 508 509 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg) 510 { 511 switch (reg) { 512 case SUN4I_I2S_FIFO_RX_REG: 513 case SUN4I_I2S_INT_STA_REG: 514 case SUN4I_I2S_RX_CNT_REG: 515 case SUN4I_I2S_TX_CNT_REG: 516 return true; 517 518 default: 519 return false; 520 } 521 } 522 523 static const struct reg_default sun4i_i2s_reg_defaults[] = { 524 { SUN4I_I2S_CTRL_REG, 0x00000000 }, 525 { SUN4I_I2S_FMT0_REG, 0x0000000c }, 526 { SUN4I_I2S_FMT1_REG, 0x00004020 }, 527 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, 528 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, 529 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, 530 { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 }, 531 { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 }, 532 { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 }, 533 { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 }, 534 }; 535 536 static const struct regmap_config sun4i_i2s_regmap_config = { 537 .reg_bits = 32, 538 .reg_stride = 4, 539 .val_bits = 32, 540 .max_register = SUN4I_I2S_RX_CHAN_MAP_REG, 541 542 .cache_type = REGCACHE_FLAT, 543 .reg_defaults = sun4i_i2s_reg_defaults, 544 .num_reg_defaults = ARRAY_SIZE(sun4i_i2s_reg_defaults), 545 .writeable_reg = sun4i_i2s_wr_reg, 546 .readable_reg = sun4i_i2s_rd_reg, 547 .volatile_reg = sun4i_i2s_volatile_reg, 548 }; 549 550 static int sun4i_i2s_runtime_resume(struct device *dev) 551 { 552 struct sun4i_i2s *i2s = dev_get_drvdata(dev); 553 int ret; 554 555 ret = clk_prepare_enable(i2s->bus_clk); 556 if (ret) { 557 dev_err(dev, "Failed to enable bus clock\n"); 558 return ret; 559 } 560 561 regcache_cache_only(i2s->regmap, false); 562 regcache_mark_dirty(i2s->regmap); 563 564 ret = regcache_sync(i2s->regmap); 565 if (ret) { 566 dev_err(dev, "Failed to sync regmap cache\n"); 567 goto err_disable_clk; 568 } 569 570 return 0; 571 572 err_disable_clk: 573 clk_disable_unprepare(i2s->bus_clk); 574 return ret; 575 } 576 577 static int sun4i_i2s_runtime_suspend(struct device *dev) 578 { 579 struct sun4i_i2s *i2s = dev_get_drvdata(dev); 580 581 regcache_cache_only(i2s->regmap, true); 582 583 clk_disable_unprepare(i2s->bus_clk); 584 585 return 0; 586 } 587 588 static int sun4i_i2s_probe(struct platform_device *pdev) 589 { 590 struct sun4i_i2s *i2s; 591 struct resource *res; 592 void __iomem *regs; 593 int irq, ret; 594 595 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 596 if (!i2s) 597 return -ENOMEM; 598 platform_set_drvdata(pdev, i2s); 599 600 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 601 regs = devm_ioremap_resource(&pdev->dev, res); 602 if (IS_ERR(regs)) 603 return PTR_ERR(regs); 604 605 irq = platform_get_irq(pdev, 0); 606 if (irq < 0) { 607 dev_err(&pdev->dev, "Can't retrieve our interrupt\n"); 608 return irq; 609 } 610 611 i2s->bus_clk = devm_clk_get(&pdev->dev, "apb"); 612 if (IS_ERR(i2s->bus_clk)) { 613 dev_err(&pdev->dev, "Can't get our bus clock\n"); 614 return PTR_ERR(i2s->bus_clk); 615 } 616 617 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 618 &sun4i_i2s_regmap_config); 619 if (IS_ERR(i2s->regmap)) { 620 dev_err(&pdev->dev, "Regmap initialisation failed\n"); 621 return PTR_ERR(i2s->regmap); 622 } 623 624 i2s->mod_clk = devm_clk_get(&pdev->dev, "mod"); 625 if (IS_ERR(i2s->mod_clk)) { 626 dev_err(&pdev->dev, "Can't get our mod clock\n"); 627 return PTR_ERR(i2s->mod_clk); 628 } 629 630 i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; 631 i2s->playback_dma_data.maxburst = 4; 632 633 pm_runtime_enable(&pdev->dev); 634 if (!pm_runtime_enabled(&pdev->dev)) { 635 ret = sun4i_i2s_runtime_resume(&pdev->dev); 636 if (ret) 637 goto err_pm_disable; 638 } 639 640 ret = devm_snd_soc_register_component(&pdev->dev, 641 &sun4i_i2s_component, 642 &sun4i_i2s_dai, 1); 643 if (ret) { 644 dev_err(&pdev->dev, "Could not register DAI\n"); 645 goto err_suspend; 646 } 647 648 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 649 if (ret) { 650 dev_err(&pdev->dev, "Could not register PCM\n"); 651 goto err_suspend; 652 } 653 654 return 0; 655 656 err_suspend: 657 if (!pm_runtime_status_suspended(&pdev->dev)) 658 sun4i_i2s_runtime_suspend(&pdev->dev); 659 err_pm_disable: 660 pm_runtime_disable(&pdev->dev); 661 662 return ret; 663 } 664 665 static int sun4i_i2s_remove(struct platform_device *pdev) 666 { 667 snd_dmaengine_pcm_unregister(&pdev->dev); 668 669 pm_runtime_disable(&pdev->dev); 670 if (!pm_runtime_status_suspended(&pdev->dev)) 671 sun4i_i2s_runtime_suspend(&pdev->dev); 672 673 return 0; 674 } 675 676 static const struct of_device_id sun4i_i2s_match[] = { 677 { .compatible = "allwinner,sun4i-a10-i2s", }, 678 {} 679 }; 680 MODULE_DEVICE_TABLE(of, sun4i_i2s_match); 681 682 static const struct dev_pm_ops sun4i_i2s_pm_ops = { 683 .runtime_resume = sun4i_i2s_runtime_resume, 684 .runtime_suspend = sun4i_i2s_runtime_suspend, 685 }; 686 687 static struct platform_driver sun4i_i2s_driver = { 688 .probe = sun4i_i2s_probe, 689 .remove = sun4i_i2s_remove, 690 .driver = { 691 .name = "sun4i-i2s", 692 .of_match_table = sun4i_i2s_match, 693 .pm = &sun4i_i2s_pm_ops, 694 }, 695 }; 696 module_platform_driver(sun4i_i2s_driver); 697 698 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>"); 699 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 700 MODULE_DESCRIPTION("Allwinner A10 I2S driver"); 701 MODULE_LICENSE("GPL"); 702