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 * for ST-Ericsson. 8 */ 9 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 #include <linux/bitops.h> 13 #include <linux/platform_device.h> 14 #include <linux/clk.h> 15 #include <linux/of.h> 16 #include <linux/regulator/consumer.h> 17 #include <linux/mfd/dbx500-prcmu.h> 18 19 #include <sound/soc.h> 20 #include <sound/soc-dai.h> 21 #include <sound/dmaengine_pcm.h> 22 23 #include "ux500_msp_i2s.h" 24 #include "ux500_msp_dai.h" 25 #include "ux500_pcm.h" 26 27 static int setup_pcm_multichan(struct snd_soc_dai *dai, 28 struct ux500_msp_config *msp_config) 29 { 30 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 31 struct msp_multichannel_config *multi = 32 &msp_config->multichannel_config; 33 34 if (drvdata->slots > 1) { 35 msp_config->multichannel_configured = 1; 36 37 multi->tx_multichannel_enable = true; 38 multi->rx_multichannel_enable = true; 39 multi->rx_comparison_enable_mode = MSP_COMPARISON_DISABLED; 40 41 multi->tx_channel_0_enable = drvdata->tx_mask; 42 multi->tx_channel_1_enable = 0; 43 multi->tx_channel_2_enable = 0; 44 multi->tx_channel_3_enable = 0; 45 46 multi->rx_channel_0_enable = drvdata->rx_mask; 47 multi->rx_channel_1_enable = 0; 48 multi->rx_channel_2_enable = 0; 49 multi->rx_channel_3_enable = 0; 50 51 dev_dbg(dai->dev, 52 "%s: Multichannel enabled. Slots: %d, TX: %u, RX: %u\n", 53 __func__, drvdata->slots, multi->tx_channel_0_enable, 54 multi->rx_channel_0_enable); 55 } 56 57 return 0; 58 } 59 60 static int setup_frameper(struct snd_soc_dai *dai, unsigned int rate, 61 struct msp_protdesc *prot_desc) 62 { 63 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 64 65 switch (drvdata->slots) { 66 case 1: 67 switch (rate) { 68 case 8000: 69 prot_desc->frame_period = 70 FRAME_PER_SINGLE_SLOT_8_KHZ; 71 break; 72 73 case 16000: 74 prot_desc->frame_period = 75 FRAME_PER_SINGLE_SLOT_16_KHZ; 76 break; 77 78 case 44100: 79 prot_desc->frame_period = 80 FRAME_PER_SINGLE_SLOT_44_1_KHZ; 81 break; 82 83 case 48000: 84 prot_desc->frame_period = 85 FRAME_PER_SINGLE_SLOT_48_KHZ; 86 break; 87 88 default: 89 dev_err(dai->dev, 90 "%s: Error: Unsupported sample-rate (freq = %d)!\n", 91 __func__, rate); 92 return -EINVAL; 93 } 94 break; 95 96 case 2: 97 prot_desc->frame_period = FRAME_PER_2_SLOTS; 98 break; 99 100 case 8: 101 prot_desc->frame_period = FRAME_PER_8_SLOTS; 102 break; 103 104 case 16: 105 prot_desc->frame_period = FRAME_PER_16_SLOTS; 106 break; 107 default: 108 dev_err(dai->dev, 109 "%s: Error: Unsupported slot-count (slots = %d)!\n", 110 __func__, drvdata->slots); 111 return -EINVAL; 112 } 113 114 prot_desc->clocks_per_frame = 115 prot_desc->frame_period+1; 116 117 dev_dbg(dai->dev, "%s: Clocks per frame: %u\n", 118 __func__, 119 prot_desc->clocks_per_frame); 120 121 return 0; 122 } 123 124 static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate, 125 struct msp_protdesc *prot_desc) 126 { 127 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 128 129 u32 frame_length = MSP_FRAME_LEN_1; 130 131 prot_desc->frame_width = 0; 132 133 switch (drvdata->slots) { 134 case 1: 135 frame_length = MSP_FRAME_LEN_1; 136 break; 137 138 case 2: 139 frame_length = MSP_FRAME_LEN_2; 140 break; 141 142 case 8: 143 frame_length = MSP_FRAME_LEN_8; 144 break; 145 146 case 16: 147 frame_length = MSP_FRAME_LEN_16; 148 break; 149 default: 150 dev_err(dai->dev, 151 "%s: Error: Unsupported slot-count (slots = %d)!\n", 152 __func__, drvdata->slots); 153 return -EINVAL; 154 } 155 156 prot_desc->tx_frame_len_1 = frame_length; 157 prot_desc->rx_frame_len_1 = frame_length; 158 prot_desc->tx_frame_len_2 = frame_length; 159 prot_desc->rx_frame_len_2 = frame_length; 160 161 prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16; 162 prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16; 163 prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16; 164 prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16; 165 166 return setup_frameper(dai, rate, prot_desc); 167 } 168 169 static int setup_clocking(struct snd_soc_dai *dai, 170 unsigned int fmt, 171 struct ux500_msp_config *msp_config) 172 { 173 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 174 case SND_SOC_DAIFMT_NB_NF: 175 break; 176 177 case SND_SOC_DAIFMT_NB_IF: 178 msp_config->tx_fsync_pol ^= 1 << TFSPOL_SHIFT; 179 msp_config->rx_fsync_pol ^= 1 << RFSPOL_SHIFT; 180 181 break; 182 183 default: 184 dev_err(dai->dev, 185 "%s: Error: Unsupported inversion (fmt = 0x%x)!\n", 186 __func__, fmt); 187 188 return -EINVAL; 189 } 190 191 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 192 case SND_SOC_DAIFMT_BC_FC: 193 dev_dbg(dai->dev, "%s: Codec is master.\n", __func__); 194 195 msp_config->iodelay = 0x20; 196 msp_config->rx_fsync_sel = 0; 197 msp_config->tx_fsync_sel = 1 << TFSSEL_SHIFT; 198 msp_config->tx_clk_sel = 0; 199 msp_config->rx_clk_sel = 0; 200 msp_config->srg_clk_sel = 0x2 << SCKSEL_SHIFT; 201 202 break; 203 204 case SND_SOC_DAIFMT_BP_FP: 205 dev_dbg(dai->dev, "%s: Codec is slave.\n", __func__); 206 207 msp_config->tx_clk_sel = TX_CLK_SEL_SRG; 208 msp_config->tx_fsync_sel = TX_SYNC_SRG_PROG; 209 msp_config->rx_clk_sel = RX_CLK_SEL_SRG; 210 msp_config->rx_fsync_sel = RX_SYNC_SRG; 211 msp_config->srg_clk_sel = 1 << SCKSEL_SHIFT; 212 213 break; 214 215 default: 216 dev_err(dai->dev, "%s: Error: Unsupported master (fmt = 0x%x)!\n", 217 __func__, fmt); 218 219 return -EINVAL; 220 } 221 222 return 0; 223 } 224 225 static int setup_pcm_protdesc(struct snd_soc_dai *dai, 226 unsigned int fmt, 227 struct msp_protdesc *prot_desc) 228 { 229 prot_desc->rx_phase_mode = MSP_SINGLE_PHASE; 230 prot_desc->tx_phase_mode = MSP_SINGLE_PHASE; 231 prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE; 232 prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE; 233 prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST; 234 prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST; 235 prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_HI); 236 prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_HI << RFSPOL_SHIFT; 237 238 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) { 239 dev_dbg(dai->dev, "%s: DSP_A.\n", __func__); 240 prot_desc->rx_clk_pol = MSP_RISING_EDGE; 241 prot_desc->tx_clk_pol = MSP_FALLING_EDGE; 242 243 prot_desc->rx_data_delay = MSP_DELAY_1; 244 prot_desc->tx_data_delay = MSP_DELAY_1; 245 } else { 246 dev_dbg(dai->dev, "%s: DSP_B.\n", __func__); 247 prot_desc->rx_clk_pol = MSP_FALLING_EDGE; 248 prot_desc->tx_clk_pol = MSP_RISING_EDGE; 249 250 prot_desc->rx_data_delay = MSP_DELAY_0; 251 prot_desc->tx_data_delay = MSP_DELAY_0; 252 } 253 254 prot_desc->rx_half_word_swap = MSP_SWAP_NONE; 255 prot_desc->tx_half_word_swap = MSP_SWAP_NONE; 256 prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR; 257 prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR; 258 prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE; 259 260 return 0; 261 } 262 263 static int setup_i2s_protdesc(struct msp_protdesc *prot_desc) 264 { 265 prot_desc->rx_phase_mode = MSP_DUAL_PHASE; 266 prot_desc->tx_phase_mode = MSP_DUAL_PHASE; 267 prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC; 268 prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC; 269 prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST; 270 prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST; 271 prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_LO); 272 prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_LO << RFSPOL_SHIFT; 273 274 prot_desc->rx_frame_len_1 = MSP_FRAME_LEN_1; 275 prot_desc->rx_frame_len_2 = MSP_FRAME_LEN_1; 276 prot_desc->tx_frame_len_1 = MSP_FRAME_LEN_1; 277 prot_desc->tx_frame_len_2 = MSP_FRAME_LEN_1; 278 prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16; 279 prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16; 280 prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16; 281 prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16; 282 283 prot_desc->rx_clk_pol = MSP_RISING_EDGE; 284 prot_desc->tx_clk_pol = MSP_FALLING_EDGE; 285 286 prot_desc->rx_data_delay = MSP_DELAY_0; 287 prot_desc->tx_data_delay = MSP_DELAY_0; 288 289 prot_desc->tx_half_word_swap = MSP_SWAP_NONE; 290 prot_desc->rx_half_word_swap = MSP_SWAP_NONE; 291 prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR; 292 prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR; 293 prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE; 294 295 return 0; 296 } 297 298 static int setup_msp_config(struct snd_pcm_substream *substream, 299 struct snd_soc_dai *dai, 300 struct ux500_msp_config *msp_config) 301 { 302 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 303 struct msp_protdesc *prot_desc = &msp_config->protdesc; 304 struct snd_pcm_runtime *runtime = substream->runtime; 305 unsigned int fmt = drvdata->fmt; 306 int ret; 307 308 memset(msp_config, 0, sizeof(*msp_config)); 309 310 msp_config->f_inputclk = drvdata->master_clk; 311 312 msp_config->tx_fifo_config = TX_FIFO_ENABLE; 313 msp_config->rx_fifo_config = RX_FIFO_ENABLE; 314 msp_config->def_elem_len = 1; 315 msp_config->direction = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 316 MSP_DIR_TX : MSP_DIR_RX; 317 msp_config->data_size = MSP_DATA_BITS_32; 318 msp_config->frame_freq = runtime->rate; 319 320 dev_dbg(dai->dev, "%s: f_inputclk = %u, frame_freq = %u.\n", 321 __func__, msp_config->f_inputclk, msp_config->frame_freq); 322 /* To avoid division by zero */ 323 prot_desc->clocks_per_frame = 1; 324 325 dev_dbg(dai->dev, "%s: rate: %u, channels: %d.\n", __func__, 326 runtime->rate, runtime->channels); 327 switch (fmt & 328 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) { 329 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BP_FP: 330 dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__); 331 332 msp_config->default_protdesc = 1; 333 msp_config->protocol = MSP_I2S_PROTOCOL; 334 break; 335 336 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BC_FC: 337 dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__); 338 339 msp_config->data_size = MSP_DATA_BITS_16; 340 msp_config->protocol = MSP_I2S_PROTOCOL; 341 342 ret = setup_i2s_protdesc(prot_desc); 343 if (ret < 0) 344 return ret; 345 346 break; 347 348 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BP_FP: 349 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BC_FC: 350 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BP_FP: 351 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BC_FC: 352 dev_dbg(dai->dev, "%s: PCM format.\n", __func__); 353 354 msp_config->data_size = MSP_DATA_BITS_16; 355 msp_config->protocol = MSP_PCM_PROTOCOL; 356 357 ret = setup_pcm_protdesc(dai, fmt, prot_desc); 358 if (ret < 0) 359 return ret; 360 361 ret = setup_pcm_multichan(dai, msp_config); 362 if (ret < 0) 363 return ret; 364 365 ret = setup_pcm_framing(dai, runtime->rate, prot_desc); 366 if (ret < 0) 367 return ret; 368 369 break; 370 371 default: 372 dev_err(dai->dev, "%s: Error: Unsupported format (%d)!\n", 373 __func__, fmt); 374 return -EINVAL; 375 } 376 377 return setup_clocking(dai, fmt, msp_config); 378 } 379 380 static int ux500_msp_dai_startup(struct snd_pcm_substream *substream, 381 struct snd_soc_dai *dai) 382 { 383 int ret = 0; 384 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 385 386 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, 387 snd_pcm_stream_str(substream)); 388 389 /* Enable regulator */ 390 ret = regulator_enable(drvdata->reg_vape); 391 if (ret != 0) { 392 dev_err(drvdata->msp->dev, 393 "%s: Failed to enable regulator!\n", __func__); 394 return ret; 395 } 396 397 /* Prepare and enable clocks */ 398 dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__); 399 ret = clk_prepare_enable(drvdata->pclk); 400 if (ret) { 401 dev_err(drvdata->msp->dev, 402 "%s: Failed to prepare/enable pclk!\n", __func__); 403 goto err_pclk; 404 } 405 406 ret = clk_prepare_enable(drvdata->clk); 407 if (ret) { 408 dev_err(drvdata->msp->dev, 409 "%s: Failed to prepare/enable clk!\n", __func__); 410 goto err_clk; 411 } 412 413 return ret; 414 err_clk: 415 clk_disable_unprepare(drvdata->pclk); 416 err_pclk: 417 regulator_disable(drvdata->reg_vape); 418 return ret; 419 } 420 421 static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, 422 struct snd_soc_dai *dai) 423 { 424 int ret; 425 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 426 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 427 428 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, 429 snd_pcm_stream_str(substream)); 430 431 if (drvdata->vape_opp_constraint == 1) { 432 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, 433 "ux500_msp_i2s", 50); 434 drvdata->vape_opp_constraint = 0; 435 } 436 437 if (ux500_msp_i2s_close(drvdata->msp, 438 is_playback ? MSP_DIR_TX : MSP_DIR_RX)) { 439 dev_err(dai->dev, 440 "%s: Error: MSP %d (%s): Unable to close i2s.\n", 441 __func__, dai->id, snd_pcm_stream_str(substream)); 442 } 443 444 /* Disable and unprepare clocks */ 445 clk_disable_unprepare(drvdata->clk); 446 clk_disable_unprepare(drvdata->pclk); 447 448 /* Disable regulator */ 449 ret = regulator_disable(drvdata->reg_vape); 450 if (ret < 0) 451 dev_err(dai->dev, 452 "%s: ERROR: Failed to disable regulator (%d)!\n", 453 __func__, ret); 454 } 455 456 static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream, 457 struct snd_soc_dai *dai) 458 { 459 int ret = 0; 460 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 461 struct snd_pcm_runtime *runtime = substream->runtime; 462 struct ux500_msp_config msp_config; 463 464 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (rate = %d).\n", __func__, 465 dai->id, snd_pcm_stream_str(substream), runtime->rate); 466 467 setup_msp_config(substream, dai, &msp_config); 468 469 ret = ux500_msp_i2s_open(drvdata->msp, &msp_config); 470 if (ret < 0) { 471 dev_err(dai->dev, "%s: Error: msp_setup failed (ret = %d)!\n", 472 __func__, ret); 473 return ret; 474 } 475 476 /* Set OPP-level */ 477 if ((drvdata->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) && 478 (drvdata->msp->f_bitclk > 19200000)) { 479 /* If the bit-clock is higher than 19.2MHz, Vape should be 480 * run in 100% OPP. Only when bit-clock is used (MSP master) 481 */ 482 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, 483 "ux500-msp-i2s", 100); 484 drvdata->vape_opp_constraint = 1; 485 } else { 486 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, 487 "ux500-msp-i2s", 50); 488 drvdata->vape_opp_constraint = 0; 489 } 490 491 return ret; 492 } 493 494 static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream, 495 struct snd_pcm_hw_params *params, 496 struct snd_soc_dai *dai) 497 { 498 unsigned int mask, slots_active; 499 struct snd_pcm_runtime *runtime = substream->runtime; 500 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 501 502 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", 503 __func__, dai->id, snd_pcm_stream_str(substream)); 504 505 switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 506 case SND_SOC_DAIFMT_I2S: 507 snd_pcm_hw_constraint_minmax(runtime, 508 SNDRV_PCM_HW_PARAM_CHANNELS, 509 1, 2); 510 break; 511 512 case SND_SOC_DAIFMT_DSP_B: 513 case SND_SOC_DAIFMT_DSP_A: 514 mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 515 drvdata->tx_mask : 516 drvdata->rx_mask; 517 518 slots_active = hweight32(mask); 519 dev_dbg(dai->dev, "TDM-slots active: %d", slots_active); 520 521 snd_pcm_hw_constraint_single(runtime, 522 SNDRV_PCM_HW_PARAM_CHANNELS, 523 slots_active); 524 break; 525 526 default: 527 dev_err(dai->dev, 528 "%s: Error: Unsupported protocol (fmt = 0x%x)!\n", 529 __func__, drvdata->fmt); 530 return -EINVAL; 531 } 532 533 return 0; 534 } 535 536 static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai, 537 unsigned int fmt) 538 { 539 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 540 541 dev_dbg(dai->dev, "%s: MSP %d: Enter.\n", __func__, dai->id); 542 543 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | 544 SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) { 545 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BP_FP: 546 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BC_FC: 547 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BP_FP: 548 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BC_FC: 549 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BP_FP: 550 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BC_FC: 551 break; 552 553 default: 554 dev_err(dai->dev, 555 "%s: Error: Unsupported protocol/master (fmt = 0x%x)!\n", 556 __func__, drvdata->fmt); 557 return -EINVAL; 558 } 559 560 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 561 case SND_SOC_DAIFMT_NB_NF: 562 case SND_SOC_DAIFMT_NB_IF: 563 case SND_SOC_DAIFMT_IB_IF: 564 break; 565 566 default: 567 dev_err(dai->dev, 568 "%s: Error: Unsupported inversion (fmt = 0x%x)!\n", 569 __func__, drvdata->fmt); 570 return -EINVAL; 571 } 572 573 drvdata->fmt = fmt; 574 return 0; 575 } 576 577 static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai, 578 unsigned int tx_mask, 579 unsigned int rx_mask, 580 int slots, int slot_width) 581 { 582 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 583 unsigned int cap; 584 585 switch (slots) { 586 case 1: 587 cap = 0x01; 588 break; 589 case 2: 590 cap = 0x03; 591 break; 592 case 8: 593 cap = 0xFF; 594 break; 595 case 16: 596 cap = 0xFFFF; 597 break; 598 default: 599 dev_err(dai->dev, "%s: Error: Unsupported slot-count (%d)!\n", 600 __func__, slots); 601 return -EINVAL; 602 } 603 drvdata->slots = slots; 604 605 if (!(slot_width == 16)) { 606 dev_err(dai->dev, "%s: Error: Unsupported slot-width (%d)!\n", 607 __func__, slot_width); 608 return -EINVAL; 609 } 610 drvdata->slot_width = slot_width; 611 612 drvdata->tx_mask = tx_mask & cap; 613 drvdata->rx_mask = rx_mask & cap; 614 615 return 0; 616 } 617 618 static int ux500_msp_dai_set_dai_sysclk(struct snd_soc_dai *dai, 619 int clk_id, unsigned int freq, int dir) 620 { 621 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 622 623 dev_dbg(dai->dev, "%s: MSP %d: Enter. clk-id: %d, freq: %u.\n", 624 __func__, dai->id, clk_id, freq); 625 626 switch (clk_id) { 627 case UX500_MSP_MASTER_CLOCK: 628 drvdata->master_clk = freq; 629 break; 630 631 default: 632 dev_err(dai->dev, "%s: MSP %d: Invalid clk-id (%d)!\n", 633 __func__, dai->id, clk_id); 634 return -EINVAL; 635 } 636 637 return 0; 638 } 639 640 static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, 641 int cmd, struct snd_soc_dai *dai) 642 { 643 int ret = 0; 644 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 645 646 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (msp->id = %d, cmd = %d).\n", 647 __func__, dai->id, snd_pcm_stream_str(substream), 648 (int)drvdata->msp->id, cmd); 649 650 ret = ux500_msp_i2s_trigger(drvdata->msp, cmd, substream->stream); 651 652 return ret; 653 } 654 655 static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai) 656 { 657 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 658 struct snd_dmaengine_dai_dma_data *playback_dma_data; 659 struct snd_dmaengine_dai_dma_data *capture_dma_data; 660 661 playback_dma_data = devm_kzalloc(dai->dev, 662 sizeof(*playback_dma_data), 663 GFP_KERNEL); 664 if (!playback_dma_data) 665 return -ENOMEM; 666 667 capture_dma_data = devm_kzalloc(dai->dev, 668 sizeof(*capture_dma_data), 669 GFP_KERNEL); 670 if (!capture_dma_data) 671 return -ENOMEM; 672 673 playback_dma_data->addr = drvdata->msp->tx_rx_addr; 674 capture_dma_data->addr = drvdata->msp->tx_rx_addr; 675 676 playback_dma_data->maxburst = 4; 677 capture_dma_data->maxburst = 4; 678 679 snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data); 680 681 return 0; 682 } 683 684 static const struct snd_soc_dai_ops ux500_msp_dai_ops[] = { 685 { 686 .probe = ux500_msp_dai_of_probe, 687 .set_sysclk = ux500_msp_dai_set_dai_sysclk, 688 .set_fmt = ux500_msp_dai_set_dai_fmt, 689 .set_tdm_slot = ux500_msp_dai_set_tdm_slot, 690 .startup = ux500_msp_dai_startup, 691 .shutdown = ux500_msp_dai_shutdown, 692 .prepare = ux500_msp_dai_prepare, 693 .trigger = ux500_msp_dai_trigger, 694 .hw_params = ux500_msp_dai_hw_params, 695 } 696 }; 697 698 static struct snd_soc_dai_driver ux500_msp_dai_drv = { 699 .playback.channels_min = UX500_MSP_MIN_CHANNELS, 700 .playback.channels_max = UX500_MSP_MAX_CHANNELS, 701 .playback.rates = UX500_I2S_RATES, 702 .playback.formats = UX500_I2S_FORMATS, 703 .capture.channels_min = UX500_MSP_MIN_CHANNELS, 704 .capture.channels_max = UX500_MSP_MAX_CHANNELS, 705 .capture.rates = UX500_I2S_RATES, 706 .capture.formats = UX500_I2S_FORMATS, 707 .ops = ux500_msp_dai_ops, 708 }; 709 710 static const struct snd_soc_component_driver ux500_msp_component = { 711 .name = "ux500-msp", 712 .legacy_dai_naming = 1, 713 }; 714 715 716 static int ux500_msp_drv_probe(struct platform_device *pdev) 717 { 718 struct ux500_msp_i2s_drvdata *drvdata; 719 int ret = 0; 720 721 drvdata = devm_kzalloc(&pdev->dev, 722 sizeof(struct ux500_msp_i2s_drvdata), 723 GFP_KERNEL); 724 if (!drvdata) 725 return -ENOMEM; 726 727 drvdata->fmt = 0; 728 drvdata->slots = 1; 729 drvdata->tx_mask = 0x01; 730 drvdata->rx_mask = 0x01; 731 drvdata->slot_width = 16; 732 drvdata->master_clk = MSP_INPUT_FREQ_APB; 733 734 drvdata->reg_vape = devm_regulator_get(&pdev->dev, "v-ape"); 735 if (IS_ERR(drvdata->reg_vape)) { 736 ret = (int)PTR_ERR(drvdata->reg_vape); 737 dev_err(&pdev->dev, 738 "%s: ERROR: Failed to get Vape supply (%d)!\n", 739 __func__, ret); 740 return ret; 741 } 742 prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); 743 744 drvdata->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); 745 if (IS_ERR(drvdata->pclk)) { 746 ret = (int)PTR_ERR(drvdata->pclk); 747 dev_err(&pdev->dev, 748 "%s: ERROR: devm_clk_get of pclk failed (%d)!\n", 749 __func__, ret); 750 return ret; 751 } 752 753 drvdata->clk = devm_clk_get(&pdev->dev, NULL); 754 if (IS_ERR(drvdata->clk)) { 755 ret = (int)PTR_ERR(drvdata->clk); 756 dev_err(&pdev->dev, 757 "%s: ERROR: devm_clk_get failed (%d)!\n", 758 __func__, ret); 759 return ret; 760 } 761 762 ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp); 763 if (!drvdata->msp) { 764 dev_err(&pdev->dev, 765 "%s: ERROR: Failed to init MSP-struct (%d)!", 766 __func__, ret); 767 return ret; 768 } 769 dev_set_drvdata(&pdev->dev, drvdata); 770 771 ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, 772 &ux500_msp_dai_drv, 1); 773 if (ret < 0) { 774 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", 775 __func__, drvdata->msp->id); 776 return ret; 777 } 778 779 ret = ux500_pcm_register_platform(pdev); 780 if (ret < 0) { 781 dev_err(&pdev->dev, 782 "Error: %s: Failed to register PCM platform device!\n", 783 __func__); 784 goto err_reg_plat; 785 } 786 787 return 0; 788 789 err_reg_plat: 790 snd_soc_unregister_component(&pdev->dev); 791 return ret; 792 } 793 794 static void ux500_msp_drv_remove(struct platform_device *pdev) 795 { 796 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 797 798 ux500_pcm_unregister_platform(pdev); 799 800 snd_soc_unregister_component(&pdev->dev); 801 802 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); 803 804 ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); 805 } 806 807 static const struct of_device_id ux500_msp_i2s_match[] = { 808 { .compatible = "stericsson,ux500-msp-i2s", }, 809 {}, 810 }; 811 MODULE_DEVICE_TABLE(of, ux500_msp_i2s_match); 812 813 static struct platform_driver msp_i2s_driver = { 814 .driver = { 815 .name = "ux500-msp-i2s", 816 .of_match_table = ux500_msp_i2s_match, 817 }, 818 .probe = ux500_msp_drv_probe, 819 .remove_new = ux500_msp_drv_remove, 820 }; 821 module_platform_driver(msp_i2s_driver); 822 823 MODULE_DESCRIPTION("ASoC Ux500 I2S driver"); 824 MODULE_LICENSE("GPL v2"); 825
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.