1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) ST-Ericsson SA 2012 4 * 5 * Author: Ola Lilja <ola.o.lilja@stericsson.com>, 6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>, 7 * Sandeep Kaushik <sandeep.kaushik@st.com> 8 * for ST-Ericsson. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <linux/delay.h> 14 #include <linux/slab.h> 15 #include <linux/io.h> 16 #include <linux/of.h> 17 18 #include <sound/soc.h> 19 20 #include "ux500_msp_i2s.h" 21 22 /* Protocol desciptors */ 23 static const struct msp_protdesc prot_descs[] = { 24 { /* I2S */ 25 MSP_SINGLE_PHASE, 26 MSP_SINGLE_PHASE, 27 MSP_PHASE2_START_MODE_IMEDIATE, 28 MSP_PHASE2_START_MODE_IMEDIATE, 29 MSP_BTF_MS_BIT_FIRST, 30 MSP_BTF_MS_BIT_FIRST, 31 MSP_FRAME_LEN_1, 32 MSP_FRAME_LEN_1, 33 MSP_FRAME_LEN_1, 34 MSP_FRAME_LEN_1, 35 MSP_ELEM_LEN_32, 36 MSP_ELEM_LEN_32, 37 MSP_ELEM_LEN_32, 38 MSP_ELEM_LEN_32, 39 MSP_DELAY_1, 40 MSP_DELAY_1, 41 MSP_RISING_EDGE, 42 MSP_FALLING_EDGE, 43 MSP_FSYNC_POL_ACT_LO, 44 MSP_FSYNC_POL_ACT_LO, 45 MSP_SWAP_NONE, 46 MSP_SWAP_NONE, 47 MSP_COMPRESS_MODE_LINEAR, 48 MSP_EXPAND_MODE_LINEAR, 49 MSP_FSYNC_IGNORE, 50 31, 51 15, 52 32, 53 }, { /* PCM */ 54 MSP_DUAL_PHASE, 55 MSP_DUAL_PHASE, 56 MSP_PHASE2_START_MODE_FSYNC, 57 MSP_PHASE2_START_MODE_FSYNC, 58 MSP_BTF_MS_BIT_FIRST, 59 MSP_BTF_MS_BIT_FIRST, 60 MSP_FRAME_LEN_1, 61 MSP_FRAME_LEN_1, 62 MSP_FRAME_LEN_1, 63 MSP_FRAME_LEN_1, 64 MSP_ELEM_LEN_16, 65 MSP_ELEM_LEN_16, 66 MSP_ELEM_LEN_16, 67 MSP_ELEM_LEN_16, 68 MSP_DELAY_0, 69 MSP_DELAY_0, 70 MSP_RISING_EDGE, 71 MSP_FALLING_EDGE, 72 MSP_FSYNC_POL_ACT_HI, 73 MSP_FSYNC_POL_ACT_HI, 74 MSP_SWAP_NONE, 75 MSP_SWAP_NONE, 76 MSP_COMPRESS_MODE_LINEAR, 77 MSP_EXPAND_MODE_LINEAR, 78 MSP_FSYNC_IGNORE, 79 255, 80 0, 81 256, 82 }, { /* Companded PCM */ 83 MSP_SINGLE_PHASE, 84 MSP_SINGLE_PHASE, 85 MSP_PHASE2_START_MODE_FSYNC, 86 MSP_PHASE2_START_MODE_FSYNC, 87 MSP_BTF_MS_BIT_FIRST, 88 MSP_BTF_MS_BIT_FIRST, 89 MSP_FRAME_LEN_1, 90 MSP_FRAME_LEN_1, 91 MSP_FRAME_LEN_1, 92 MSP_FRAME_LEN_1, 93 MSP_ELEM_LEN_8, 94 MSP_ELEM_LEN_8, 95 MSP_ELEM_LEN_8, 96 MSP_ELEM_LEN_8, 97 MSP_DELAY_0, 98 MSP_DELAY_0, 99 MSP_RISING_EDGE, 100 MSP_RISING_EDGE, 101 MSP_FSYNC_POL_ACT_HI, 102 MSP_FSYNC_POL_ACT_HI, 103 MSP_SWAP_NONE, 104 MSP_SWAP_NONE, 105 MSP_COMPRESS_MODE_LINEAR, 106 MSP_EXPAND_MODE_LINEAR, 107 MSP_FSYNC_IGNORE, 108 255, 109 0, 110 256, 111 }, 112 }; 113 114 static void set_prot_desc_tx(struct ux500_msp *msp, 115 struct msp_protdesc *protdesc, 116 enum msp_data_size data_size) 117 { 118 u32 temp_reg = 0; 119 120 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode); 121 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode); 122 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1); 123 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2); 124 if (msp->def_elem_len) { 125 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1); 126 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2); 127 } else { 128 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size); 129 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size); 130 } 131 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay); 132 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order); 133 temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol); 134 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap); 135 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode); 136 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore); 137 138 writel(temp_reg, msp->registers + MSP_TCF); 139 } 140 141 static void set_prot_desc_rx(struct ux500_msp *msp, 142 struct msp_protdesc *protdesc, 143 enum msp_data_size data_size) 144 { 145 u32 temp_reg = 0; 146 147 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode); 148 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode); 149 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1); 150 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2); 151 if (msp->def_elem_len) { 152 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1); 153 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2); 154 } else { 155 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size); 156 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size); 157 } 158 159 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay); 160 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order); 161 temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol); 162 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap); 163 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode); 164 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore); 165 166 writel(temp_reg, msp->registers + MSP_RCF); 167 } 168 169 static int configure_protocol(struct ux500_msp *msp, 170 struct ux500_msp_config *config) 171 { 172 struct msp_protdesc *protdesc; 173 enum msp_data_size data_size; 174 u32 temp_reg = 0; 175 176 data_size = config->data_size; 177 msp->def_elem_len = config->def_elem_len; 178 if (config->default_protdesc == 1) { 179 if (config->protocol >= MSP_INVALID_PROTOCOL) { 180 dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n", 181 __func__); 182 return -EINVAL; 183 } 184 protdesc = 185 (struct msp_protdesc *)&prot_descs[config->protocol]; 186 } else { 187 protdesc = (struct msp_protdesc *)&config->protdesc; 188 } 189 190 if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) { 191 dev_err(msp->dev, 192 "%s: ERROR: Invalid data-size requested (data_size = %d)!\n", 193 __func__, data_size); 194 return -EINVAL; 195 } 196 197 if (config->direction & MSP_DIR_TX) 198 set_prot_desc_tx(msp, protdesc, data_size); 199 if (config->direction & MSP_DIR_RX) 200 set_prot_desc_rx(msp, protdesc, data_size); 201 202 /* The code below should not be separated. */ 203 temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING; 204 temp_reg |= MSP_TX_CLKPOL_BIT(!protdesc->tx_clk_pol ^ 205 config->bclk_inverted); 206 writel(temp_reg, msp->registers + MSP_GCR); 207 temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING; 208 temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol ^ 209 config->bclk_inverted); 210 writel(temp_reg, msp->registers + MSP_GCR); 211 212 return 0; 213 } 214 215 static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config) 216 { 217 struct msp_protdesc *protdesc; 218 u64 desired_bitclk; 219 unsigned int bitclk; 220 u32 reg_val_GCR; 221 u32 sck_div; 222 u32 temp_reg; 223 224 reg_val_GCR = readl(msp->registers + MSP_GCR); 225 writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR); 226 227 switch (config->protocol) { 228 case MSP_PCM_PROTOCOL: 229 case MSP_PCM_COMPAND_PROTOCOL: 230 case MSP_I2S_PROTOCOL: 231 break; 232 default: 233 dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n", 234 __func__, 235 config->protocol); 236 return -EINVAL; 237 } 238 239 if (config->default_protdesc) 240 protdesc = (struct msp_protdesc *)&prot_descs[config->protocol]; 241 else 242 protdesc = &config->protdesc; 243 244 if (!config->frame_freq || !protdesc->clocks_per_frame) 245 return -EINVAL; 246 247 desired_bitclk = (u64)config->frame_freq * protdesc->clocks_per_frame; 248 if (desired_bitclk > config->f_inputclk) 249 return -EINVAL; 250 bitclk = desired_bitclk; 251 if (config->f_inputclk % bitclk) { 252 dev_err(msp->dev, 253 "Input clock %u cannot generate bit clock %u\n", 254 config->f_inputclk, bitclk); 255 return -EINVAL; 256 } 257 258 sck_div = config->f_inputclk / bitclk; 259 if (!sck_div || sck_div > SCK_DIV_MASK + 1) 260 return -EINVAL; 261 262 temp_reg = (sck_div - 1) & SCK_DIV_MASK; 263 temp_reg |= FRAME_WIDTH_BITS(protdesc->frame_width); 264 temp_reg |= FRAME_PERIOD_BITS(protdesc->frame_period); 265 writel(temp_reg, msp->registers + MSP_SRG); 266 267 msp->f_bitclk = config->f_inputclk / sck_div; 268 269 /* Enable bit-clock */ 270 udelay(100); 271 reg_val_GCR = readl(msp->registers + MSP_GCR); 272 writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR); 273 udelay(100); 274 275 return 0; 276 } 277 278 static int configure_multichannel(struct ux500_msp *msp, 279 struct ux500_msp_config *config) 280 { 281 struct msp_protdesc *protdesc; 282 struct msp_multichannel_config *mcfg; 283 u32 reg_val_MCR; 284 285 if (config->default_protdesc == 1) { 286 if (config->protocol >= MSP_INVALID_PROTOCOL) { 287 dev_err(msp->dev, 288 "%s: ERROR: Invalid protocol (%d)!\n", 289 __func__, config->protocol); 290 return -EINVAL; 291 } 292 protdesc = (struct msp_protdesc *) 293 &prot_descs[config->protocol]; 294 } else { 295 protdesc = (struct msp_protdesc *)&config->protdesc; 296 } 297 298 mcfg = &config->multichannel_config; 299 if (mcfg->tx_multichannel_enable) { 300 if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) { 301 reg_val_MCR = readl(msp->registers + MSP_MCR); 302 writel(reg_val_MCR | (mcfg->tx_multichannel_enable ? 303 1 << TMCEN_BIT : 0), 304 msp->registers + MSP_MCR); 305 writel(mcfg->tx_channel_0_enable, 306 msp->registers + MSP_TCE0); 307 writel(mcfg->tx_channel_1_enable, 308 msp->registers + MSP_TCE1); 309 writel(mcfg->tx_channel_2_enable, 310 msp->registers + MSP_TCE2); 311 writel(mcfg->tx_channel_3_enable, 312 msp->registers + MSP_TCE3); 313 } else { 314 dev_err(msp->dev, 315 "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n", 316 __func__, protdesc->tx_phase_mode); 317 return -EINVAL; 318 } 319 } 320 if (mcfg->rx_multichannel_enable) { 321 if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) { 322 reg_val_MCR = readl(msp->registers + MSP_MCR); 323 writel(reg_val_MCR | (mcfg->rx_multichannel_enable ? 324 1 << RMCEN_BIT : 0), 325 msp->registers + MSP_MCR); 326 writel(mcfg->rx_channel_0_enable, 327 msp->registers + MSP_RCE0); 328 writel(mcfg->rx_channel_1_enable, 329 msp->registers + MSP_RCE1); 330 writel(mcfg->rx_channel_2_enable, 331 msp->registers + MSP_RCE2); 332 writel(mcfg->rx_channel_3_enable, 333 msp->registers + MSP_RCE3); 334 } else { 335 dev_err(msp->dev, 336 "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n", 337 __func__, protdesc->rx_phase_mode); 338 return -EINVAL; 339 } 340 if (mcfg->rx_comparison_enable_mode) { 341 reg_val_MCR = readl(msp->registers + MSP_MCR); 342 writel(reg_val_MCR | 343 (mcfg->rx_comparison_enable_mode << RCMPM_BIT), 344 msp->registers + MSP_MCR); 345 346 writel(mcfg->comparison_mask, 347 msp->registers + MSP_RCM); 348 writel(mcfg->comparison_value, 349 msp->registers + MSP_RCV); 350 351 } 352 } 353 354 return 0; 355 } 356 357 static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config, 358 bool first) 359 { 360 int status; 361 u32 reg_val_DMACR; 362 363 /* Configure msp with protocol dependent settings */ 364 status = configure_protocol(msp, config); 365 if (status) 366 return status; 367 368 if (first && config->clock_provider) { 369 status = setup_bitclk(msp, config); 370 if (status) 371 return status; 372 } 373 374 if (config->multichannel_configured == 1) { 375 status = configure_multichannel(msp, config); 376 if (status) 377 return status; 378 } 379 380 reg_val_DMACR = readl(msp->registers + MSP_DMACR); 381 if (config->direction & MSP_DIR_RX) 382 reg_val_DMACR |= RX_DMA_ENABLE; 383 if (config->direction & MSP_DIR_TX) 384 reg_val_DMACR |= TX_DMA_ENABLE; 385 writel(reg_val_DMACR, msp->registers + MSP_DMACR); 386 387 writel(config->iodelay, msp->registers + MSP_IODLY); 388 389 return 0; 390 } 391 392 static void flush_fifo_rx(struct ux500_msp *msp) 393 { 394 u32 reg_val_GCR, reg_val_FLR; 395 u32 limit = 32; 396 397 reg_val_GCR = readl(msp->registers + MSP_GCR); 398 writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR); 399 400 reg_val_FLR = readl(msp->registers + MSP_FLR); 401 while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) { 402 readl(msp->registers + MSP_DR); 403 reg_val_FLR = readl(msp->registers + MSP_FLR); 404 } 405 406 writel(reg_val_GCR, msp->registers + MSP_GCR); 407 } 408 409 static void flush_fifo_tx(struct ux500_msp *msp) 410 { 411 u32 reg_val_GCR, reg_val_FLR; 412 u32 limit = 32; 413 414 reg_val_GCR = readl(msp->registers + MSP_GCR); 415 writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR); 416 writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR); 417 418 reg_val_FLR = readl(msp->registers + MSP_FLR); 419 while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) { 420 readl(msp->registers + MSP_TSTDR); 421 reg_val_FLR = readl(msp->registers + MSP_FLR); 422 } 423 writel(0x0, msp->registers + MSP_ITCR); 424 writel(reg_val_GCR, msp->registers + MSP_GCR); 425 } 426 427 static bool ux500_msp_config_compatible(struct ux500_msp *msp, 428 struct ux500_msp_config *config) 429 { 430 struct ux500_msp_config *active = &msp->config; 431 432 return active->f_inputclk == config->f_inputclk && 433 active->tx_clk_sel == config->tx_clk_sel && 434 active->rx_clk_sel == config->rx_clk_sel && 435 active->srg_clk_sel == config->srg_clk_sel && 436 active->rx_fsync_pol == config->rx_fsync_pol && 437 active->tx_fsync_pol == config->tx_fsync_pol && 438 active->rx_fsync_sel == config->rx_fsync_sel && 439 active->tx_fsync_sel == config->tx_fsync_sel && 440 active->default_protdesc == config->default_protdesc && 441 active->protocol == config->protocol && 442 active->frame_freq == config->frame_freq && 443 active->data_size == config->data_size && 444 active->def_elem_len == config->def_elem_len && 445 active->clock_provider == config->clock_provider && 446 active->bclk_inverted == config->bclk_inverted && 447 !memcmp(&active->protdesc, &config->protdesc, 448 sizeof(active->protdesc)); 449 } 450 451 int ux500_msp_i2s_open(struct ux500_msp *msp, 452 struct ux500_msp_config *config) 453 { 454 u32 old_reg, new_reg, mask; 455 int res; 456 unsigned int tx_sel, rx_sel, tx_busy, rx_busy; 457 bool first; 458 459 if (in_interrupt()) { 460 dev_err(msp->dev, 461 "%s: ERROR: Open called in interrupt context!\n", 462 __func__); 463 return -1; 464 } 465 466 tx_sel = (config->direction & MSP_DIR_TX) > 0; 467 rx_sel = (config->direction & MSP_DIR_RX) > 0; 468 if (!tx_sel && !rx_sel) { 469 dev_err(msp->dev, "%s: Error: No direction selected!\n", 470 __func__); 471 return -EINVAL; 472 } 473 474 tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0; 475 rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0; 476 if (tx_busy && tx_sel) { 477 dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__); 478 return -EBUSY; 479 } 480 if (rx_busy && rx_sel) { 481 dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__); 482 return -EBUSY; 483 } 484 485 first = !msp->dir_busy; 486 if (!first && !ux500_msp_config_compatible(msp, config)) { 487 dev_err(msp->dev, "%s: Incompatible duplex configuration\n", 488 __func__); 489 return -EBUSY; 490 } 491 492 if (first) { 493 /* First do the global config register */ 494 mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK | 495 TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK | 496 RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | 497 SRG_CLK_SEL_MASK | LOOPBACK_MASK | TX_EXTRA_DELAY_MASK; 498 499 new_reg = config->tx_clk_sel | config->rx_clk_sel | 500 config->rx_fsync_pol | config->tx_fsync_pol | 501 config->rx_fsync_sel | config->tx_fsync_sel | 502 config->rx_fifo_config | config->tx_fifo_config | 503 config->srg_clk_sel | config->loopback_enable | 504 config->tx_data_enable; 505 506 old_reg = readl(msp->registers + MSP_GCR); 507 old_reg &= ~mask; 508 new_reg |= old_reg; 509 writel(new_reg, msp->registers + MSP_GCR); 510 writel(MSP_WMRK_TX_4_ELEMENTS | MSP_WMRK_RX_4_ELEMENTS, 511 msp->registers + MSP_WMRK); 512 } 513 514 res = enable_msp(msp, config, first); 515 if (res < 0) { 516 dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n", 517 __func__, res); 518 if (tx_sel) 519 writel(0, msp->registers + MSP_TCF); 520 if (rx_sel) 521 writel(0, msp->registers + MSP_RCF); 522 if (first) { 523 writel(0, msp->registers + MSP_GCR); 524 writel(0, msp->registers + MSP_DMACR); 525 writel(0, msp->registers + MSP_SRG); 526 writel(0, msp->registers + MSP_MCR); 527 } 528 return res; 529 } 530 531 msp->dir_busy |= config->direction; 532 if (first) { 533 msp->config = *config; 534 msp->clock_provider = config->clock_provider; 535 } 536 if (config->loopback_enable & 0x80) 537 msp->loopback_enable = 1; 538 539 /* Flush FIFOs */ 540 if (tx_sel) 541 flush_fifo_tx(msp); 542 if (rx_sel) 543 flush_fifo_rx(msp); 544 545 if (!msp->dir_running) 546 msp->msp_state = MSP_STATE_CONFIGURED; 547 return 0; 548 } 549 550 static void disable_msp_rx(struct ux500_msp *msp) 551 { 552 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC; 553 554 reg_val_GCR = readl(msp->registers + MSP_GCR); 555 writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR); 556 reg_val_DMACR = readl(msp->registers + MSP_DMACR); 557 writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR); 558 reg_val_IMSC = readl(msp->registers + MSP_IMSC); 559 writel(reg_val_IMSC & 560 ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT), 561 msp->registers + MSP_IMSC); 562 563 } 564 565 static void disable_msp_tx(struct ux500_msp *msp) 566 { 567 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC; 568 569 reg_val_GCR = readl(msp->registers + MSP_GCR); 570 writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR); 571 reg_val_DMACR = readl(msp->registers + MSP_DMACR); 572 writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR); 573 reg_val_IMSC = readl(msp->registers + MSP_IMSC); 574 writel(reg_val_IMSC & 575 ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT), 576 msp->registers + MSP_IMSC); 577 578 } 579 580 static int disable_msp(struct ux500_msp *msp, unsigned int dir) 581 { 582 u32 reg_val_GCR; 583 unsigned int disable_tx, disable_rx; 584 585 reg_val_GCR = readl(msp->registers + MSP_GCR); 586 disable_tx = dir & MSP_DIR_TX; 587 disable_rx = dir & MSP_DIR_RX; 588 if (disable_tx && disable_rx) { 589 reg_val_GCR = readl(msp->registers + MSP_GCR); 590 writel(reg_val_GCR | LOOPBACK_MASK, 591 msp->registers + MSP_GCR); 592 593 /* Flush TX-FIFO */ 594 flush_fifo_tx(msp); 595 596 /* Disable TX-channel */ 597 writel((readl(msp->registers + MSP_GCR) & 598 (~TX_ENABLE)), msp->registers + MSP_GCR); 599 600 /* Flush RX-FIFO */ 601 flush_fifo_rx(msp); 602 603 /* Disable Loopback and Receive channel */ 604 writel((readl(msp->registers + MSP_GCR) & 605 (~(RX_ENABLE | LOOPBACK_MASK))), 606 msp->registers + MSP_GCR); 607 608 disable_msp_tx(msp); 609 disable_msp_rx(msp); 610 } else if (disable_tx) 611 disable_msp_tx(msp); 612 else if (disable_rx) 613 disable_msp_rx(msp); 614 615 return 0; 616 } 617 618 int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction) 619 { 620 u32 reg_val_DMACR, reg_val_GCR, dma_enable_bit, enable_bit; 621 unsigned int dir; 622 623 if (direction == SNDRV_PCM_STREAM_PLAYBACK) 624 dir = MSP_DIR_TX; 625 else if (direction == SNDRV_PCM_STREAM_CAPTURE) 626 dir = MSP_DIR_RX; 627 else 628 return -EINVAL; 629 630 if (msp->msp_state == MSP_STATE_IDLE) { 631 dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n", 632 __func__); 633 return -EINVAL; 634 } 635 636 switch (cmd) { 637 case SNDRV_PCM_TRIGGER_START: 638 case SNDRV_PCM_TRIGGER_RESUME: 639 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 640 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 641 enable_bit = TX_ENABLE; 642 dma_enable_bit = TX_DMA_ENABLE; 643 } else { 644 enable_bit = RX_ENABLE; 645 dma_enable_bit = RX_DMA_ENABLE; 646 } 647 if (!(msp->dir_busy & dir)) 648 return -EINVAL; 649 reg_val_DMACR = readl(msp->registers + MSP_DMACR); 650 writel(reg_val_DMACR | dma_enable_bit, 651 msp->registers + MSP_DMACR); 652 reg_val_GCR = readl(msp->registers + MSP_GCR); 653 if (msp->clock_provider) 654 enable_bit |= FRAME_GEN_ENABLE; 655 writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR); 656 msp->dir_running |= dir; 657 msp->msp_state = MSP_STATE_RUNNING; 658 break; 659 660 case SNDRV_PCM_TRIGGER_STOP: 661 case SNDRV_PCM_TRIGGER_SUSPEND: 662 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 663 if (!(msp->dir_busy & dir)) 664 return -EINVAL; 665 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 666 disable_msp_tx(msp); 667 msp->dir_running &= ~MSP_DIR_TX; 668 } else { 669 disable_msp_rx(msp); 670 msp->dir_running &= ~MSP_DIR_RX; 671 } 672 if (!msp->dir_running) { 673 reg_val_GCR = readl(msp->registers + MSP_GCR); 674 writel(reg_val_GCR & ~FRAME_GEN_ENABLE, 675 msp->registers + MSP_GCR); 676 msp->msp_state = MSP_STATE_CONFIGURED; 677 } 678 break; 679 default: 680 return -EINVAL; 681 } 682 683 return 0; 684 } 685 686 int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) 687 { 688 int status = 0; 689 690 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); 691 692 if (!dir || dir & ~(MSP_DIR_TX | MSP_DIR_RX) || 693 (msp->dir_busy & dir) != dir) 694 return -EINVAL; 695 696 status = disable_msp(msp, dir); 697 msp->dir_busy &= ~dir; 698 msp->dir_running &= ~dir; 699 if (msp->dir_busy && !msp->dir_running) { 700 writel(readl(msp->registers + MSP_GCR) & ~FRAME_GEN_ENABLE, 701 msp->registers + MSP_GCR); 702 msp->msp_state = MSP_STATE_CONFIGURED; 703 } 704 if (msp->dir_busy == 0) { 705 /* disable sample rate and frame generators */ 706 msp->msp_state = MSP_STATE_IDLE; 707 writel((readl(msp->registers + MSP_GCR) & 708 (~(FRAME_GEN_ENABLE | SRG_ENABLE))), 709 msp->registers + MSP_GCR); 710 711 writel(0, msp->registers + MSP_GCR); 712 writel(0, msp->registers + MSP_TCF); 713 writel(0, msp->registers + MSP_RCF); 714 writel(0, msp->registers + MSP_DMACR); 715 writel(0, msp->registers + MSP_SRG); 716 writel(0, msp->registers + MSP_MCR); 717 writel(0, msp->registers + MSP_RCM); 718 writel(0, msp->registers + MSP_RCV); 719 writel(0, msp->registers + MSP_TCE0); 720 writel(0, msp->registers + MSP_TCE1); 721 writel(0, msp->registers + MSP_TCE2); 722 writel(0, msp->registers + MSP_TCE3); 723 writel(0, msp->registers + MSP_RCE0); 724 writel(0, msp->registers + MSP_RCE1); 725 writel(0, msp->registers + MSP_RCE2); 726 writel(0, msp->registers + MSP_RCE3); 727 memset(&msp->config, 0, sizeof(msp->config)); 728 msp->clock_provider = false; 729 } 730 731 return status; 732 733 } 734 735 int ux500_msp_i2s_init_msp(struct platform_device *pdev, 736 struct ux500_msp **msp_p) 737 { 738 struct resource *res; 739 struct ux500_msp *msp; 740 741 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); 742 msp = *msp_p; 743 if (!msp) 744 return -ENOMEM; 745 746 msp->dev = &pdev->dev; 747 748 msp->registers = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 749 if (IS_ERR(msp->registers)) 750 return PTR_ERR(msp->registers); 751 msp->tx_rx_addr = res->start + MSP_DR; 752 753 msp->msp_state = MSP_STATE_IDLE; 754 msp->loopback_enable = 0; 755 756 return 0; 757 } 758 759 void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, 760 struct ux500_msp *msp) 761 { 762 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); 763 } 764 765 MODULE_LICENSE("GPL v2"); 766