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