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