1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/clk.h> 4 #include <linux/delay.h> 5 #include <linux/io.h> 6 #include <linux/module.h> 7 #include <linux/of.h> 8 #include <linux/platform_device.h> 9 #include <sound/dmaengine_pcm.h> 10 #include <sound/pcm_params.h> 11 #include <sound/soc.h> 12 #include <linux/string.h> 13 #include <linux/dev_printk.h> 14 15 #include <linux/bitfield.h> 16 #include <linux/bits.h> 17 #include <linux/limits.h> 18 #include <linux/overflow.h> 19 20 #define TX_FIFO_SIZE (1024) 21 #define RX_FIFO_SIZE (1024) 22 #define TX_MAX_BURST (8) 23 #define RX_MAX_BURST (8) 24 25 #define CV1800B_DEF_FREQ 24576000 26 #define CV1800B_DEF_MCLK_FS_RATIO 256 27 28 /* tdm registers */ 29 #define CV1800B_BLK_MODE_SETTING 0x000 30 #define CV1800B_FRAME_SETTING 0x004 31 #define CV1800B_SLOT_SETTING1 0x008 32 #define CV1800B_SLOT_SETTING2 0x00C 33 #define CV1800B_DATA_FORMAT 0x010 34 #define CV1800B_BLK_CFG 0x014 35 #define CV1800B_I2S_ENABLE 0x018 36 #define CV1800B_I2S_RESET 0x01C 37 #define CV1800B_I2S_INT_EN 0x020 38 #define CV1800B_I2S_INT 0x024 39 #define CV1800B_FIFO_THRESHOLD 0x028 40 #define CV1800B_LRCK_MASTER 0x02C /* special clock only mode */ 41 #define CV1800B_FIFO_RESET 0x030 42 #define CV1800B_RX_STATUS 0x040 43 #define CV1800B_TX_STATUS 0x048 44 #define CV1800B_CLK_CTRL0 0x060 45 #define CV1800B_CLK_CTRL1 0x064 46 #define CV1800B_PCM_SYNTH 0x068 47 #define CV1800B_RX_RD_PORT 0x080 48 #define CV1800B_TX_WR_PORT 0x0C0 49 50 /* CV1800B_BLK_MODE_SETTING (0x000) */ 51 #define BLK_TX_MODE_MASK GENMASK(0, 0) 52 #define BLK_MASTER_MODE_MASK GENMASK(1, 1) 53 #define BLK_DMA_MODE_MASK GENMASK(7, 7) 54 55 /* CV1800B_CLK_CTRL1 (0x064) */ 56 #define CLK_MCLK_DIV_MASK GENMASK(15, 0) 57 #define CLK_BCLK_DIV_MASK GENMASK(31, 16) 58 59 /* CV1800B_CLK_CTRL0 (0x060) */ 60 #define CLK_AUD_CLK_SEL_MASK GENMASK(0, 0) 61 #define CLK_BCLK_OUT_CLK_FORCE_EN_MASK GENMASK(6, 6) 62 #define CLK_MCLK_OUT_EN_MASK GENMASK(7, 7) 63 #define CLK_AUD_EN_MASK GENMASK(8, 8) 64 65 /* CV1800B_I2S_RESET (0x01C) */ 66 #define RST_I2S_RESET_RX_MASK GENMASK(0, 0) 67 #define RST_I2S_RESET_TX_MASK GENMASK(1, 1) 68 69 /* CV1800B_FIFO_RESET (0x030) */ 70 #define FIFO_RX_RESET_MASK GENMASK(0, 0) 71 #define FIFO_TX_RESET_MASK GENMASK(16, 16) 72 73 /* CV1800B_I2S_ENABLE (0x018) */ 74 #define I2S_ENABLE_MASK GENMASK(0, 0) 75 76 /* CV1800B_BLK_CFG (0x014) */ 77 #define BLK_AUTO_DISABLE_WITH_CH_EN_MASK GENMASK(4, 4) 78 #define BLK_RX_BLK_CLK_FORCE_EN_MASK GENMASK(8, 8) 79 #define BLK_RX_FIFO_DMA_CLK_FORCE_EN_MASK GENMASK(9, 9) 80 #define BLK_TX_BLK_CLK_FORCE_EN_MASK GENMASK(16, 16) 81 #define BLK_TX_FIFO_DMA_CLK_FORCE_EN_MASK GENMASK(17, 17) 82 83 /* CV1800B_FRAME_SETTING (0x004) */ 84 #define FRAME_LENGTH_MASK GENMASK(8, 0) 85 #define FS_ACTIVE_LENGTH_MASK GENMASK(23, 16) 86 87 /* CV1800B_I2S_INT_EN (0x020) */ 88 #define INT_I2S_INT_EN_MASK GENMASK(8, 8) 89 90 /* CV1800B_SLOT_SETTING2 (0x00C) */ 91 #define SLOT_EN_MASK GENMASK(15, 0) 92 93 /* CV1800B_LRCK_MASTER (0x02C) */ 94 #define LRCK_MASTER_ENABLE_MASK GENMASK(0, 0) 95 96 /* CV1800B_DATA_FORMAT (0x010) */ 97 #define DF_WORD_LENGTH_MASK GENMASK(2, 1) 98 #define DF_TX_SOURCE_LEFT_ALIGN_MASK GENMASK(6, 6) 99 100 /* CV1800B_FIFO_THRESHOLD (0x028) */ 101 #define FIFO_RX_THRESHOLD_MASK GENMASK(4, 0) 102 #define FIFO_TX_THRESHOLD_MASK GENMASK(20, 16) 103 #define FIFO_TX_HIGH_THRESHOLD_MASK GENMASK(28, 24) 104 105 /* CV1800B_SLOT_SETTING1 (0x008) */ 106 #define SLOT_NUM_MASK GENMASK(3, 0) 107 #define SLOT_SIZE_MASK GENMASK(13, 8) 108 #define DATA_SIZE_MASK GENMASK(20, 16) 109 #define FB_OFFSET_MASK GENMASK(28, 24) 110 111 enum cv1800b_tdm_word_length { 112 CV1800B_WORD_LENGTH_8_BIT = 0, 113 CV1800B_WORD_LENGTH_16_BIT = 1, 114 CV1800B_WORD_LENGTH_32_BIT = 2, 115 }; 116 117 struct cv1800b_i2s { 118 void __iomem *base; 119 struct clk *clk; 120 struct clk *sysclk; 121 struct device *dev; 122 struct snd_dmaengine_dai_dma_data playback_dma; 123 struct snd_dmaengine_dai_dma_data capture_dma; 124 u32 mclk_rate; 125 bool bclk_ratio_fixed; 126 u32 bclk_ratio; 127 128 }; 129 130 static void cv1800b_setup_dma_struct(struct cv1800b_i2s *i2s, 131 phys_addr_t phys_base) 132 { 133 i2s->playback_dma.addr = phys_base + CV1800B_TX_WR_PORT; 134 i2s->playback_dma.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 135 i2s->playback_dma.fifo_size = TX_FIFO_SIZE; 136 i2s->playback_dma.maxburst = TX_MAX_BURST; 137 138 i2s->capture_dma.addr = phys_base + CV1800B_RX_RD_PORT; 139 i2s->capture_dma.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 140 i2s->capture_dma.fifo_size = RX_FIFO_SIZE; 141 i2s->capture_dma.maxburst = RX_MAX_BURST; 142 } 143 144 static const struct snd_dmaengine_pcm_config cv1800b_i2s_pcm_config = { 145 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 146 }; 147 148 static void cv1800b_reset_fifo(struct cv1800b_i2s *i2s) 149 { 150 u32 val; 151 152 val = readl(i2s->base + CV1800B_FIFO_RESET); 153 val = u32_replace_bits(val, 1, FIFO_RX_RESET_MASK); 154 val = u32_replace_bits(val, 1, FIFO_TX_RESET_MASK); 155 writel(val, i2s->base + CV1800B_FIFO_RESET); 156 157 usleep_range(10, 20); 158 159 val = readl(i2s->base + CV1800B_FIFO_RESET); 160 val = u32_replace_bits(val, 0, FIFO_RX_RESET_MASK); 161 val = u32_replace_bits(val, 0, FIFO_TX_RESET_MASK); 162 writel(val, i2s->base + CV1800B_FIFO_RESET); 163 } 164 165 static void cv1800b_reset_i2s(struct cv1800b_i2s *i2s) 166 { 167 u32 val; 168 169 val = readl(i2s->base + CV1800B_I2S_RESET); 170 val = u32_replace_bits(val, 1, RST_I2S_RESET_RX_MASK); 171 val = u32_replace_bits(val, 1, RST_I2S_RESET_TX_MASK); 172 writel(val, i2s->base + CV1800B_I2S_RESET); 173 174 usleep_range(10, 20); 175 176 val = readl(i2s->base + CV1800B_I2S_RESET); 177 val = u32_replace_bits(val, 0, RST_I2S_RESET_RX_MASK); 178 val = u32_replace_bits(val, 0, RST_I2S_RESET_TX_MASK); 179 writel(val, i2s->base + CV1800B_I2S_RESET); 180 } 181 182 static void cv1800b_set_mclk_div(struct cv1800b_i2s *i2s, u32 mclk_div) 183 { 184 u32 val; 185 186 val = readl(i2s->base + CV1800B_CLK_CTRL1); 187 val = u32_replace_bits(val, mclk_div, CLK_MCLK_DIV_MASK); 188 writel(val, i2s->base + CV1800B_CLK_CTRL1); 189 dev_dbg(i2s->dev, "mclk_div is set to %u\n", mclk_div); 190 } 191 192 static void cv1800b_set_tx_mode(struct cv1800b_i2s *i2s, bool is_tx) 193 { 194 u32 val; 195 196 val = readl(i2s->base + CV1800B_BLK_MODE_SETTING); 197 val = u32_replace_bits(val, is_tx, BLK_TX_MODE_MASK); 198 writel(val, i2s->base + CV1800B_BLK_MODE_SETTING); 199 dev_dbg(i2s->dev, "tx_mode is set to %u\n", is_tx); 200 } 201 202 static int cv1800b_set_bclk_div(struct cv1800b_i2s *i2s, u32 bclk_div) 203 { 204 u32 val; 205 206 if (bclk_div == 0 || bclk_div > 0xFFFF) 207 return -EINVAL; 208 209 val = readl(i2s->base + CV1800B_CLK_CTRL1); 210 val = u32_replace_bits(val, bclk_div, CLK_BCLK_DIV_MASK); 211 writel(val, i2s->base + CV1800B_CLK_CTRL1); 212 dev_dbg(i2s->dev, "bclk_div is set to %u\n", bclk_div); 213 return 0; 214 } 215 216 /* set memory width of audio data , reg word_length */ 217 static int cv1800b_set_word_length(struct cv1800b_i2s *i2s, 218 unsigned int physical_width) 219 { 220 u8 word_length_val; 221 u32 val; 222 223 switch (physical_width) { 224 case 8: 225 word_length_val = CV1800B_WORD_LENGTH_8_BIT; 226 break; 227 case 16: 228 word_length_val = CV1800B_WORD_LENGTH_16_BIT; 229 break; 230 case 32: 231 word_length_val = CV1800B_WORD_LENGTH_32_BIT; 232 break; 233 default: 234 dev_dbg(i2s->dev, "can't set word_length field\n"); 235 return -EINVAL; 236 } 237 238 val = readl(i2s->base + CV1800B_DATA_FORMAT); 239 val = u32_replace_bits(val, word_length_val, DF_WORD_LENGTH_MASK); 240 writel(val, i2s->base + CV1800B_DATA_FORMAT); 241 return 0; 242 } 243 244 static void cv1800b_enable_clocks(struct cv1800b_i2s *i2s, bool enabled) 245 { 246 u32 val; 247 248 val = readl(i2s->base + CV1800B_CLK_CTRL0); 249 val = u32_replace_bits(val, enabled, CLK_AUD_EN_MASK); 250 writel(val, i2s->base + CV1800B_CLK_CTRL0); 251 } 252 253 static int cv1800b_set_slot_settings(struct cv1800b_i2s *i2s, u32 slots, 254 u32 physical_width, u32 data_size) 255 { 256 u32 slot_num; 257 u32 slot_size; 258 u32 frame_length; 259 u32 frame_active_length; 260 u32 val; 261 262 if (!slots || !physical_width || !data_size) { 263 dev_err(i2s->dev, "frame or slot settings are not valid\n"); 264 return -EINVAL; 265 } 266 if (slots > 16 || physical_width > 64 || data_size > 32) { 267 dev_err(i2s->dev, "frame or slot settings are not valid\n"); 268 return -EINVAL; 269 } 270 271 slot_num = slots - 1; 272 slot_size = physical_width - 1; 273 frame_length = (physical_width * slots) - 1; 274 frame_active_length = physical_width - 1; 275 276 if (frame_length > 511 || frame_active_length > 255) { 277 dev_err(i2s->dev, "frame or slot settings are not valid\n"); 278 return -EINVAL; 279 } 280 281 val = readl(i2s->base + CV1800B_SLOT_SETTING1); 282 val = u32_replace_bits(val, slot_size, SLOT_SIZE_MASK); 283 val = u32_replace_bits(val, data_size - 1, DATA_SIZE_MASK); 284 val = u32_replace_bits(val, slot_num, SLOT_NUM_MASK); 285 writel(val, i2s->base + CV1800B_SLOT_SETTING1); 286 287 val = readl(i2s->base + CV1800B_FRAME_SETTING); 288 val = u32_replace_bits(val, frame_length, FRAME_LENGTH_MASK); 289 val = u32_replace_bits(val, frame_active_length, FS_ACTIVE_LENGTH_MASK); 290 writel(val, i2s->base + CV1800B_FRAME_SETTING); 291 292 dev_dbg(i2s->dev, "slot settings num: %u width: %u\n", slots, physical_width); 293 return 0; 294 } 295 296 /* 297 * calculate mclk_div. 298 * if requested value is bigger than optimal 299 * leave mclk_div as 1. cff clock is capable 300 * to handle it 301 */ 302 static int cv1800b_calc_mclk_div(unsigned int target_mclk, u32 *mclk_div) 303 { 304 *mclk_div = 1; 305 306 if (target_mclk == 0) 307 return -EINVAL; 308 309 /* optimal parent frequency is close to CV1800B_DEF_FREQ */ 310 if (target_mclk < CV1800B_DEF_FREQ) { 311 *mclk_div = DIV_ROUND_CLOSEST(CV1800B_DEF_FREQ, target_mclk); 312 if (!*mclk_div || *mclk_div > 0xFFFF) 313 return -EINVAL; 314 } 315 return 0; 316 } 317 318 /* 319 * set CCF clock and divider for this clock 320 * mclk_clock = ccf_clock / mclk_div 321 */ 322 static int cv1800b_i2s_set_rate_for_mclk(struct cv1800b_i2s *i2s, 323 unsigned int target_mclk) 324 { 325 u32 mclk_div = 1; 326 u64 tmp; 327 int ret; 328 unsigned long clk_rate; 329 unsigned long actual; 330 331 ret = cv1800b_calc_mclk_div(target_mclk, &mclk_div); 332 if (ret) { 333 dev_dbg(i2s->dev, "can't calc mclk_div for freq %u\n", 334 target_mclk); 335 return ret; 336 } 337 338 tmp = (u64)target_mclk * mclk_div; 339 if (tmp > ULONG_MAX) { 340 dev_err(i2s->dev, "clk_rate overflow: freq=%u div=%u\n", 341 target_mclk, mclk_div); 342 return -ERANGE; 343 } 344 345 clk_rate = (unsigned long)tmp; 346 347 cv1800b_enable_clocks(i2s, false); 348 349 ret = clk_set_rate(i2s->sysclk, clk_rate); 350 if (ret) 351 return ret; 352 353 actual = clk_get_rate(i2s->sysclk); 354 if (clk_rate != actual) { 355 dev_err_ratelimited(i2s->dev, 356 "clk_set_rate failed %lu, actual is %lu\n", 357 clk_rate, actual); 358 } 359 360 cv1800b_set_mclk_div(i2s, mclk_div); 361 cv1800b_enable_clocks(i2s, true); 362 363 return 0; 364 } 365 366 static int cv1800b_i2s_hw_params(struct snd_pcm_substream *substream, 367 struct snd_pcm_hw_params *params, 368 struct snd_soc_dai *dai) 369 { 370 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 371 unsigned int rate = params_rate(params); 372 unsigned int channels = params_channels(params); 373 unsigned int physical_width = params_physical_width(params); 374 int data_width = params_width(params); 375 bool tx_mode = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 1 : 0; 376 int ret; 377 u32 bclk_div; 378 u32 bclk_ratio; 379 u32 mclk_rate; 380 u32 tmp; 381 382 if (data_width < 0) 383 return data_width; 384 385 if (!channels || !rate || !physical_width) 386 return -EINVAL; 387 388 ret = cv1800b_set_slot_settings(i2s, channels, physical_width, data_width); 389 if (ret) 390 return ret; 391 392 if (i2s->mclk_rate) { 393 mclk_rate = i2s->mclk_rate; 394 } else { 395 dev_dbg(i2s->dev, "mclk is not set by machine driver\n"); 396 ret = cv1800b_i2s_set_rate_for_mclk(i2s, 397 rate * CV1800B_DEF_MCLK_FS_RATIO); 398 if (ret) 399 return ret; 400 mclk_rate = rate * CV1800B_DEF_MCLK_FS_RATIO; 401 } 402 403 bclk_ratio = (i2s->bclk_ratio_fixed) ? i2s->bclk_ratio : 404 (physical_width * channels); 405 406 if (check_mul_overflow(rate, bclk_ratio, &tmp)) 407 return -EOVERFLOW; 408 409 if (!tmp) 410 return -EINVAL; 411 if (mclk_rate % tmp) 412 dev_warn(i2s->dev, "mclk rate is not aligned to bclk or rate\n"); 413 414 bclk_div = DIV_ROUND_CLOSEST(mclk_rate, tmp); 415 416 ret = cv1800b_set_bclk_div(i2s, bclk_div); 417 if (ret) 418 return ret; 419 420 ret = cv1800b_set_word_length(i2s, physical_width); 421 if (ret) 422 return ret; 423 424 cv1800b_set_tx_mode(i2s, tx_mode); 425 426 cv1800b_reset_fifo(i2s); 427 cv1800b_reset_i2s(i2s); 428 return 0; 429 } 430 431 static int cv1800b_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 432 struct snd_soc_dai *dai) 433 { 434 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 435 u32 val; 436 437 val = readl(i2s->base + CV1800B_I2S_ENABLE); 438 439 switch (cmd) { 440 case SNDRV_PCM_TRIGGER_START: 441 case SNDRV_PCM_TRIGGER_RESUME: 442 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 443 val = u32_replace_bits(val, 1, I2S_ENABLE_MASK); 444 break; 445 446 case SNDRV_PCM_TRIGGER_STOP: 447 case SNDRV_PCM_TRIGGER_SUSPEND: 448 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 449 val = u32_replace_bits(val, 0, I2S_ENABLE_MASK); 450 break; 451 default: 452 return -EINVAL; 453 } 454 writel(val, i2s->base + CV1800B_I2S_ENABLE); 455 return 0; 456 } 457 458 static int cv1800b_i2s_startup(struct snd_pcm_substream *substream, 459 struct snd_soc_dai *dai) 460 { 461 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 462 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 463 struct snd_soc_dai_link *dai_link = rtd->dai_link; 464 465 dev_dbg(i2s->dev, "%s: dai=%s substream=%d\n", __func__, dai->name, 466 substream->stream); 467 /** 468 * Ensure DMA is stopped before DAI 469 * shutdown (prevents DW AXI DMAC stop/busy on next open). 470 */ 471 dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC; 472 return 0; 473 } 474 475 static int cv1800b_i2s_dai_probe(struct snd_soc_dai *dai) 476 { 477 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 478 479 if (!i2s) { 480 dev_err(dai->dev, "no drvdata in DAI probe\n"); 481 return -ENODEV; 482 } 483 484 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma, &i2s->capture_dma); 485 return 0; 486 } 487 488 static int cv1800b_i2s_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 489 { 490 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 491 u32 val; 492 u32 master; 493 494 /* only i2s format is supported */ 495 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) 496 return -EINVAL; 497 498 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 499 case SND_SOC_DAIFMT_CBP_CFP: 500 dev_dbg(i2s->dev, "set to master mode\n"); 501 master = 1; 502 break; 503 504 case SND_SOC_DAIFMT_CBC_CFC: 505 dev_dbg(i2s->dev, "set to slave mode\n"); 506 master = 0; 507 break; 508 default: 509 return -EINVAL; 510 } 511 512 val = readl(i2s->base + CV1800B_BLK_MODE_SETTING); 513 val = u32_replace_bits(val, master, BLK_MASTER_MODE_MASK); 514 writel(val, i2s->base + CV1800B_BLK_MODE_SETTING); 515 return 0; 516 } 517 518 static int cv1800b_i2s_dai_set_bclk_ratio(struct snd_soc_dai *dai, 519 unsigned int ratio) 520 { 521 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 522 523 if (ratio == 0) 524 return -EINVAL; 525 i2s->bclk_ratio = ratio; 526 i2s->bclk_ratio_fixed = true; 527 return 0; 528 } 529 530 static int cv1800b_i2s_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 531 unsigned int freq, int dir) 532 { 533 struct cv1800b_i2s *i2s = snd_soc_dai_get_drvdata(dai); 534 int ret; 535 u32 val; 536 bool output_enable = (dir == SND_SOC_CLOCK_OUT) ? true : false; 537 538 dev_dbg(i2s->dev, "%s called with %u\n", __func__, freq); 539 ret = cv1800b_i2s_set_rate_for_mclk(i2s, freq); 540 if (ret) 541 return ret; 542 543 val = readl(i2s->base + CV1800B_CLK_CTRL0); 544 val = u32_replace_bits(val, output_enable, CLK_MCLK_OUT_EN_MASK); 545 writel(val, i2s->base + CV1800B_CLK_CTRL0); 546 547 i2s->mclk_rate = freq; 548 return 0; 549 } 550 551 static const struct snd_soc_dai_ops cv1800b_i2s_dai_ops = { 552 .probe = cv1800b_i2s_dai_probe, 553 .startup = cv1800b_i2s_startup, 554 .hw_params = cv1800b_i2s_hw_params, 555 .trigger = cv1800b_i2s_trigger, 556 .set_fmt = cv1800b_i2s_dai_set_fmt, 557 .set_bclk_ratio = cv1800b_i2s_dai_set_bclk_ratio, 558 .set_sysclk = cv1800b_i2s_dai_set_sysclk, 559 }; 560 561 static const struct snd_soc_dai_driver cv1800b_i2s_dai_template = { 562 .name = "cv1800b-i2s", 563 .playback = { 564 .stream_name = "Playback", 565 .channels_min = 1, 566 .channels_max = 2, 567 .rates = SNDRV_PCM_RATE_8000_192000, 568 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, 569 }, 570 .capture = { 571 .stream_name = "Capture", 572 .channels_min = 1, 573 .channels_max = 2, 574 .rates = SNDRV_PCM_RATE_8000_192000, 575 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, 576 }, 577 .ops = &cv1800b_i2s_dai_ops, 578 }; 579 580 static const struct snd_soc_component_driver cv1800b_i2s_component = { 581 .name = "cv1800b-i2s", 582 }; 583 584 static void cv1800b_i2s_hw_disable(struct cv1800b_i2s *i2s) 585 { 586 u32 val; 587 588 val = readl(i2s->base + CV1800B_I2S_ENABLE); 589 val = u32_replace_bits(val, 0, I2S_ENABLE_MASK); 590 writel(val, i2s->base + CV1800B_I2S_ENABLE); 591 592 val = readl(i2s->base + CV1800B_CLK_CTRL0); 593 val = u32_replace_bits(val, 0, CLK_AUD_EN_MASK); 594 val = u32_replace_bits(val, 0, CLK_MCLK_OUT_EN_MASK); 595 writel(val, i2s->base + CV1800B_CLK_CTRL0); 596 597 val = readl(i2s->base + CV1800B_I2S_RESET); 598 val = u32_replace_bits(val, 1, RST_I2S_RESET_RX_MASK); 599 val = u32_replace_bits(val, 1, RST_I2S_RESET_TX_MASK); 600 writel(val, i2s->base + CV1800B_I2S_RESET); 601 602 val = readl(i2s->base + CV1800B_FIFO_RESET); 603 val = u32_replace_bits(val, 1, FIFO_RX_RESET_MASK); 604 val = u32_replace_bits(val, 1, FIFO_TX_RESET_MASK); 605 writel(val, i2s->base + CV1800B_FIFO_RESET); 606 } 607 608 static void cv1800b_i2s_setup_tdm(struct cv1800b_i2s *i2s) 609 { 610 u32 val; 611 612 val = readl(i2s->base + CV1800B_BLK_MODE_SETTING); 613 val = u32_replace_bits(val, 1, BLK_DMA_MODE_MASK); 614 writel(val, i2s->base + CV1800B_BLK_MODE_SETTING); 615 616 val = readl(i2s->base + CV1800B_CLK_CTRL0); 617 val = u32_replace_bits(val, 0, CLK_AUD_CLK_SEL_MASK); 618 val = u32_replace_bits(val, 0, CLK_MCLK_OUT_EN_MASK); 619 val = u32_replace_bits(val, 0, CLK_AUD_EN_MASK); 620 writel(val, i2s->base + CV1800B_CLK_CTRL0); 621 622 val = readl(i2s->base + CV1800B_FIFO_THRESHOLD); 623 val = u32_replace_bits(val, 4, FIFO_RX_THRESHOLD_MASK); 624 val = u32_replace_bits(val, 4, FIFO_TX_THRESHOLD_MASK); 625 val = u32_replace_bits(val, 4, FIFO_TX_HIGH_THRESHOLD_MASK); 626 writel(val, i2s->base + CV1800B_FIFO_THRESHOLD); 627 628 val = readl(i2s->base + CV1800B_I2S_ENABLE); 629 val = u32_replace_bits(val, 0, I2S_ENABLE_MASK); 630 writel(val, i2s->base + CV1800B_I2S_ENABLE); 631 } 632 633 static int cv1800b_i2s_probe(struct platform_device *pdev) 634 { 635 struct device *dev = &pdev->dev; 636 struct cv1800b_i2s *i2s; 637 struct resource *res; 638 void __iomem *regs; 639 struct snd_soc_dai_driver *dai; 640 int ret; 641 642 i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL); 643 if (!i2s) 644 return -ENOMEM; 645 646 regs = devm_platform_ioremap_resource(pdev, 0); 647 if (IS_ERR(regs)) 648 return PTR_ERR(regs); 649 i2s->dev = &pdev->dev; 650 i2s->base = regs; 651 652 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 653 if (!res) 654 return -ENODEV; 655 cv1800b_setup_dma_struct(i2s, res->start); 656 657 i2s->clk = devm_clk_get_enabled(dev, "i2s"); 658 if (IS_ERR(i2s->clk)) 659 return dev_err_probe(dev, PTR_ERR(i2s->clk), 660 "failed to get+enable i2s\n"); 661 i2s->sysclk = devm_clk_get_enabled(dev, "mclk"); 662 if (IS_ERR(i2s->sysclk)) 663 return dev_err_probe(dev, PTR_ERR(i2s->sysclk), 664 "failed to get+enable mclk\n"); 665 666 platform_set_drvdata(pdev, i2s); 667 cv1800b_i2s_setup_tdm(i2s); 668 669 dai = devm_kmemdup(dev, &cv1800b_i2s_dai_template, sizeof(*dai), 670 GFP_KERNEL); 671 if (!dai) 672 return -ENOMEM; 673 674 ret = devm_snd_soc_register_component(dev, &cv1800b_i2s_component, dai, 675 1); 676 if (ret) 677 return ret; 678 679 ret = devm_snd_dmaengine_pcm_register(dev, &cv1800b_i2s_pcm_config, 0); 680 if (ret) { 681 dev_err(dev, "dmaengine_pcm_register failed: %d\n", ret); 682 return ret; 683 } 684 685 return 0; 686 } 687 688 static void cv1800b_i2s_remove(struct platform_device *pdev) 689 { 690 struct cv1800b_i2s *i2s = platform_get_drvdata(pdev); 691 692 if (!i2s) 693 return; 694 cv1800b_i2s_hw_disable(i2s); 695 } 696 697 static const struct of_device_id cv1800b_i2s_of_match[] = { 698 { .compatible = "sophgo,cv1800b-i2s" }, 699 { /* sentinel */ } 700 }; 701 702 MODULE_DEVICE_TABLE(of, cv1800b_i2s_of_match); 703 704 static struct platform_driver cv1800b_i2s_driver = { 705 .probe = cv1800b_i2s_probe, 706 .remove = cv1800b_i2s_remove, 707 .driver = { 708 .name = "cv1800b-i2s", 709 .of_match_table = cv1800b_i2s_of_match, 710 }, 711 }; 712 module_platform_driver(cv1800b_i2s_driver); 713 714 MODULE_DESCRIPTION("Sophgo cv1800b I2S/TDM driver"); 715 MODULE_AUTHOR("Anton D. Stavinsky <stavinsky@gmail.com>"); 716 MODULE_LICENSE("GPL"); 717