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