1 // SPDX-License-Identifier: GPL-2.0-only 2 // SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. 3 // All rights reserved. 4 // 5 // tegra210_admaif.c - Tegra ADMAIF driver 6 7 #include <linux/clk.h> 8 #include <linux/device.h> 9 #include <linux/module.h> 10 #include <linux/of_platform.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/regmap.h> 14 #include <sound/pcm_params.h> 15 #include <sound/soc.h> 16 #include "tegra_isomgr_bw.h" 17 #include "tegra210_admaif.h" 18 #include "tegra_cif.h" 19 #include "tegra_pcm.h" 20 21 #define CH_REG(offset, reg, id) \ 22 ((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id))) 23 24 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id) 25 26 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id) 27 28 #define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base, cif_ctrl) \ 29 { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \ 30 { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), cif_ctrl }, \ 31 { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \ 32 { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \ 33 { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), cif_ctrl }, \ 34 { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl } 35 36 #define ADMAIF_REG_DEFAULTS(id, chip) \ 37 REG_DEFAULTS((id) - 1, \ 38 chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \ 39 chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \ 40 chip ## _ADMAIF_TX_BASE, \ 41 chip ## _ADMAIF_RX_BASE, \ 42 chip ## _ADMAIF_CIF_REG_DEFAULT) 43 44 static const struct reg_default tegra186_admaif_reg_defaults[] = { 45 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003}, 46 ADMAIF_REG_DEFAULTS(1, TEGRA186), 47 ADMAIF_REG_DEFAULTS(2, TEGRA186), 48 ADMAIF_REG_DEFAULTS(3, TEGRA186), 49 ADMAIF_REG_DEFAULTS(4, TEGRA186), 50 ADMAIF_REG_DEFAULTS(5, TEGRA186), 51 ADMAIF_REG_DEFAULTS(6, TEGRA186), 52 ADMAIF_REG_DEFAULTS(7, TEGRA186), 53 ADMAIF_REG_DEFAULTS(8, TEGRA186), 54 ADMAIF_REG_DEFAULTS(9, TEGRA186), 55 ADMAIF_REG_DEFAULTS(10, TEGRA186), 56 ADMAIF_REG_DEFAULTS(11, TEGRA186), 57 ADMAIF_REG_DEFAULTS(12, TEGRA186), 58 ADMAIF_REG_DEFAULTS(13, TEGRA186), 59 ADMAIF_REG_DEFAULTS(14, TEGRA186), 60 ADMAIF_REG_DEFAULTS(15, TEGRA186), 61 ADMAIF_REG_DEFAULTS(16, TEGRA186), 62 ADMAIF_REG_DEFAULTS(17, TEGRA186), 63 ADMAIF_REG_DEFAULTS(18, TEGRA186), 64 ADMAIF_REG_DEFAULTS(19, TEGRA186), 65 ADMAIF_REG_DEFAULTS(20, TEGRA186) 66 }; 67 68 static const struct reg_default tegra210_admaif_reg_defaults[] = { 69 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003}, 70 ADMAIF_REG_DEFAULTS(1, TEGRA210), 71 ADMAIF_REG_DEFAULTS(2, TEGRA210), 72 ADMAIF_REG_DEFAULTS(3, TEGRA210), 73 ADMAIF_REG_DEFAULTS(4, TEGRA210), 74 ADMAIF_REG_DEFAULTS(5, TEGRA210), 75 ADMAIF_REG_DEFAULTS(6, TEGRA210), 76 ADMAIF_REG_DEFAULTS(7, TEGRA210), 77 ADMAIF_REG_DEFAULTS(8, TEGRA210), 78 ADMAIF_REG_DEFAULTS(9, TEGRA210), 79 ADMAIF_REG_DEFAULTS(10, TEGRA210) 80 }; 81 82 static const struct reg_default tegra264_admaif_reg_defaults[] = { 83 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA264_ADMAIF_GLOBAL_BASE), 0x00000003}, 84 ADMAIF_REG_DEFAULTS(1, TEGRA264), 85 ADMAIF_REG_DEFAULTS(2, TEGRA264), 86 ADMAIF_REG_DEFAULTS(3, TEGRA264), 87 ADMAIF_REG_DEFAULTS(4, TEGRA264), 88 ADMAIF_REG_DEFAULTS(5, TEGRA264), 89 ADMAIF_REG_DEFAULTS(6, TEGRA264), 90 ADMAIF_REG_DEFAULTS(7, TEGRA264), 91 ADMAIF_REG_DEFAULTS(8, TEGRA264), 92 ADMAIF_REG_DEFAULTS(9, TEGRA264), 93 ADMAIF_REG_DEFAULTS(10, TEGRA264), 94 ADMAIF_REG_DEFAULTS(11, TEGRA264), 95 ADMAIF_REG_DEFAULTS(12, TEGRA264), 96 ADMAIF_REG_DEFAULTS(13, TEGRA264), 97 ADMAIF_REG_DEFAULTS(14, TEGRA264), 98 ADMAIF_REG_DEFAULTS(15, TEGRA264), 99 ADMAIF_REG_DEFAULTS(16, TEGRA264), 100 ADMAIF_REG_DEFAULTS(17, TEGRA264), 101 ADMAIF_REG_DEFAULTS(18, TEGRA264), 102 ADMAIF_REG_DEFAULTS(19, TEGRA264), 103 ADMAIF_REG_DEFAULTS(20, TEGRA264), 104 ADMAIF_REG_DEFAULTS(21, TEGRA264), 105 ADMAIF_REG_DEFAULTS(22, TEGRA264), 106 ADMAIF_REG_DEFAULTS(23, TEGRA264), 107 ADMAIF_REG_DEFAULTS(24, TEGRA264), 108 ADMAIF_REG_DEFAULTS(25, TEGRA264), 109 ADMAIF_REG_DEFAULTS(26, TEGRA264), 110 ADMAIF_REG_DEFAULTS(27, TEGRA264), 111 ADMAIF_REG_DEFAULTS(28, TEGRA264), 112 ADMAIF_REG_DEFAULTS(29, TEGRA264), 113 ADMAIF_REG_DEFAULTS(30, TEGRA264), 114 ADMAIF_REG_DEFAULTS(31, TEGRA264), 115 ADMAIF_REG_DEFAULTS(32, TEGRA264) 116 }; 117 118 static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg) 119 { 120 struct tegra_admaif *admaif = dev_get_drvdata(dev); 121 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE; 122 unsigned int num_ch = admaif->soc_data->num_ch; 123 unsigned int rx_base = admaif->soc_data->rx_base; 124 unsigned int tx_base = admaif->soc_data->tx_base; 125 unsigned int global_base = admaif->soc_data->global_base; 126 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; 127 unsigned int rx_max = rx_base + (num_ch * ch_stride); 128 unsigned int tx_max = tx_base + (num_ch * ch_stride); 129 130 if ((reg >= rx_base) && (reg < rx_max)) { 131 reg = (reg - rx_base) % ch_stride; 132 if ((reg == TEGRA_ADMAIF_RX_ENABLE) || 133 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) || 134 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) || 135 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL)) 136 return true; 137 } else if ((reg >= tx_base) && (reg < tx_max)) { 138 reg = (reg - tx_base) % ch_stride; 139 if ((reg == TEGRA_ADMAIF_TX_ENABLE) || 140 (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) || 141 (reg == TEGRA_ADMAIF_TX_SOFT_RESET) || 142 (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL)) 143 return true; 144 } else if ((reg >= global_base) && (reg < reg_max)) { 145 if (reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) 146 return true; 147 } 148 149 return false; 150 } 151 152 static bool tegra_admaif_rd_reg(struct device *dev, unsigned int reg) 153 { 154 struct tegra_admaif *admaif = dev_get_drvdata(dev); 155 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE; 156 unsigned int num_ch = admaif->soc_data->num_ch; 157 unsigned int rx_base = admaif->soc_data->rx_base; 158 unsigned int tx_base = admaif->soc_data->tx_base; 159 unsigned int global_base = admaif->soc_data->global_base; 160 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; 161 unsigned int rx_max = rx_base + (num_ch * ch_stride); 162 unsigned int tx_max = tx_base + (num_ch * ch_stride); 163 164 if ((reg >= rx_base) && (reg < rx_max)) { 165 reg = (reg - rx_base) % ch_stride; 166 if ((reg == TEGRA_ADMAIF_RX_ENABLE) || 167 (reg == TEGRA_ADMAIF_RX_STATUS) || 168 (reg == TEGRA_ADMAIF_RX_INT_STATUS) || 169 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) || 170 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) || 171 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL)) 172 return true; 173 } else if ((reg >= tx_base) && (reg < tx_max)) { 174 reg = (reg - tx_base) % ch_stride; 175 if ((reg == TEGRA_ADMAIF_TX_ENABLE) || 176 (reg == TEGRA_ADMAIF_TX_STATUS) || 177 (reg == TEGRA_ADMAIF_TX_INT_STATUS) || 178 (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) || 179 (reg == TEGRA_ADMAIF_TX_SOFT_RESET) || 180 (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL)) 181 return true; 182 } else if ((reg >= global_base) && (reg < reg_max)) { 183 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) || 184 (reg == (global_base + TEGRA_ADMAIF_GLOBAL_CG_0)) || 185 (reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) || 186 (reg == (global_base + 187 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) || 188 (reg == (global_base + 189 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS))) 190 return true; 191 } 192 193 return false; 194 } 195 196 static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg) 197 { 198 struct tegra_admaif *admaif = dev_get_drvdata(dev); 199 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE; 200 unsigned int num_ch = admaif->soc_data->num_ch; 201 unsigned int rx_base = admaif->soc_data->rx_base; 202 unsigned int tx_base = admaif->soc_data->tx_base; 203 unsigned int global_base = admaif->soc_data->global_base; 204 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; 205 unsigned int rx_max = rx_base + (num_ch * ch_stride); 206 unsigned int tx_max = tx_base + (num_ch * ch_stride); 207 208 if ((reg >= rx_base) && (reg < rx_max)) { 209 reg = (reg - rx_base) % ch_stride; 210 if ((reg == TEGRA_ADMAIF_RX_ENABLE) || 211 (reg == TEGRA_ADMAIF_RX_STATUS) || 212 (reg == TEGRA_ADMAIF_RX_INT_STATUS) || 213 (reg == TEGRA_ADMAIF_RX_SOFT_RESET)) 214 return true; 215 } else if ((reg >= tx_base) && (reg < tx_max)) { 216 reg = (reg - tx_base) % ch_stride; 217 if ((reg == TEGRA_ADMAIF_TX_ENABLE) || 218 (reg == TEGRA_ADMAIF_TX_STATUS) || 219 (reg == TEGRA_ADMAIF_TX_INT_STATUS) || 220 (reg == TEGRA_ADMAIF_TX_SOFT_RESET)) 221 return true; 222 } else if ((reg >= global_base) && (reg < reg_max)) { 223 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) || 224 (reg == (global_base + 225 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) || 226 (reg == (global_base + 227 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS))) 228 return true; 229 } 230 231 return false; 232 } 233 234 static const struct regmap_config tegra210_admaif_regmap_config = { 235 .reg_bits = 32, 236 .reg_stride = 4, 237 .val_bits = 32, 238 .max_register = TEGRA210_ADMAIF_LAST_REG, 239 .writeable_reg = tegra_admaif_wr_reg, 240 .readable_reg = tegra_admaif_rd_reg, 241 .volatile_reg = tegra_admaif_volatile_reg, 242 .reg_defaults = tegra210_admaif_reg_defaults, 243 .num_reg_defaults = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1, 244 .cache_type = REGCACHE_FLAT, 245 }; 246 247 static const struct regmap_config tegra186_admaif_regmap_config = { 248 .reg_bits = 32, 249 .reg_stride = 4, 250 .val_bits = 32, 251 .max_register = TEGRA186_ADMAIF_LAST_REG, 252 .writeable_reg = tegra_admaif_wr_reg, 253 .readable_reg = tegra_admaif_rd_reg, 254 .volatile_reg = tegra_admaif_volatile_reg, 255 .reg_defaults = tegra186_admaif_reg_defaults, 256 .num_reg_defaults = TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1, 257 .cache_type = REGCACHE_FLAT, 258 }; 259 260 static const struct regmap_config tegra264_admaif_regmap_config = { 261 .reg_bits = 32, 262 .reg_stride = 4, 263 .val_bits = 32, 264 .max_register = TEGRA264_ADMAIF_LAST_REG, 265 .writeable_reg = tegra_admaif_wr_reg, 266 .readable_reg = tegra_admaif_rd_reg, 267 .volatile_reg = tegra_admaif_volatile_reg, 268 .reg_defaults = tegra264_admaif_reg_defaults, 269 .num_reg_defaults = TEGRA264_ADMAIF_CHANNEL_COUNT * 6 + 1, 270 .cache_type = REGCACHE_FLAT, 271 }; 272 273 static int tegra_admaif_runtime_suspend(struct device *dev) 274 { 275 struct tegra_admaif *admaif = dev_get_drvdata(dev); 276 277 regcache_cache_only(admaif->regmap, true); 278 regcache_mark_dirty(admaif->regmap); 279 280 return 0; 281 } 282 283 static int tegra_admaif_runtime_resume(struct device *dev) 284 { 285 struct tegra_admaif *admaif = dev_get_drvdata(dev); 286 287 regcache_cache_only(admaif->regmap, false); 288 regcache_sync(admaif->regmap); 289 290 return 0; 291 } 292 293 static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg, 294 int valid_bit) 295 { 296 switch (valid_bit) { 297 case DATA_8BIT: 298 regmap_update_bits(map, reg, PACK8_EN_MASK, PACK8_EN); 299 regmap_update_bits(map, reg, PACK16_EN_MASK, 0); 300 break; 301 case DATA_16BIT: 302 regmap_update_bits(map, reg, PACK16_EN_MASK, PACK16_EN); 303 regmap_update_bits(map, reg, PACK8_EN_MASK, 0); 304 break; 305 case DATA_32BIT: 306 regmap_update_bits(map, reg, PACK16_EN_MASK, 0); 307 regmap_update_bits(map, reg, PACK8_EN_MASK, 0); 308 break; 309 default: 310 return -EINVAL; 311 } 312 313 return 0; 314 } 315 316 static int tegra_admaif_prepare(struct snd_pcm_substream *substream, 317 struct snd_soc_dai *dai) 318 { 319 return tegra_isomgr_adma_setbw(substream, dai, true); 320 } 321 322 static void tegra_admaif_shutdown(struct snd_pcm_substream *substream, 323 struct snd_soc_dai *dai) 324 { 325 tegra_isomgr_adma_setbw(substream, dai, false); 326 } 327 328 static int tegra_admaif_hw_params(struct snd_pcm_substream *substream, 329 struct snd_pcm_hw_params *params, 330 struct snd_soc_dai *dai) 331 { 332 struct device *dev = dai->dev; 333 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); 334 struct tegra_cif_conf cif_conf; 335 unsigned int reg, path; 336 int valid_bit, channels; 337 338 memset(&cif_conf, 0, sizeof(struct tegra_cif_conf)); 339 340 switch (params_format(params)) { 341 case SNDRV_PCM_FORMAT_S8: 342 cif_conf.audio_bits = TEGRA_ACIF_BITS_8; 343 cif_conf.client_bits = TEGRA_ACIF_BITS_8; 344 valid_bit = DATA_8BIT; 345 break; 346 case SNDRV_PCM_FORMAT_S16_LE: 347 cif_conf.audio_bits = TEGRA_ACIF_BITS_16; 348 cif_conf.client_bits = TEGRA_ACIF_BITS_16; 349 valid_bit = DATA_16BIT; 350 break; 351 case SNDRV_PCM_FORMAT_S24_LE: 352 cif_conf.audio_bits = TEGRA_ACIF_BITS_32; 353 cif_conf.client_bits = TEGRA_ACIF_BITS_24; 354 valid_bit = DATA_32BIT; 355 break; 356 case SNDRV_PCM_FORMAT_S32_LE: 357 cif_conf.audio_bits = TEGRA_ACIF_BITS_32; 358 cif_conf.client_bits = TEGRA_ACIF_BITS_32; 359 valid_bit = DATA_32BIT; 360 break; 361 default: 362 dev_err(dev, "unsupported format!\n"); 363 return -EOPNOTSUPP; 364 } 365 366 channels = params_channels(params); 367 cif_conf.client_ch = channels; 368 cif_conf.audio_ch = channels; 369 370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 371 path = ADMAIF_TX_PATH; 372 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id); 373 } else { 374 path = ADMAIF_RX_PATH; 375 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id); 376 } 377 378 cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id]; 379 cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id]; 380 381 tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit); 382 383 if (admaif->soc_data->max_stream_ch == TEGRA264_ADMAIF_MAX_CHANNEL) 384 tegra264_set_cif(admaif->regmap, reg, &cif_conf); 385 else 386 tegra_set_cif(admaif->regmap, reg, &cif_conf); 387 388 return 0; 389 } 390 391 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction) 392 { 393 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); 394 unsigned int reg, mask, val; 395 396 switch (direction) { 397 case SNDRV_PCM_STREAM_PLAYBACK: 398 mask = TX_ENABLE_MASK; 399 val = TX_ENABLE; 400 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id); 401 break; 402 case SNDRV_PCM_STREAM_CAPTURE: 403 mask = RX_ENABLE_MASK; 404 val = RX_ENABLE; 405 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id); 406 break; 407 default: 408 return -EINVAL; 409 } 410 411 regmap_update_bits(admaif->regmap, reg, mask, val); 412 413 return 0; 414 } 415 416 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction) 417 { 418 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); 419 unsigned int enable_reg, status_reg, reset_reg, mask, val; 420 char *dir_name; 421 int err, enable; 422 423 switch (direction) { 424 case SNDRV_PCM_STREAM_PLAYBACK: 425 mask = TX_ENABLE_MASK; 426 enable = TX_ENABLE; 427 dir_name = "TX"; 428 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id); 429 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id); 430 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id); 431 break; 432 case SNDRV_PCM_STREAM_CAPTURE: 433 mask = RX_ENABLE_MASK; 434 enable = RX_ENABLE; 435 dir_name = "RX"; 436 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id); 437 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id); 438 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id); 439 break; 440 default: 441 return -EINVAL; 442 } 443 444 /* Disable TX/RX channel */ 445 regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable); 446 447 /* Wait until ADMAIF TX/RX status is disabled */ 448 err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val, 449 !(val & enable), 10, 10000); 450 if (err < 0) 451 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n", 452 dai->id + 1, dir_name); 453 454 /* SW reset */ 455 regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET); 456 457 /* Wait till SW reset is complete */ 458 err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val, 459 !(val & SW_RESET_MASK & SW_RESET), 460 10, 10000); 461 if (err) { 462 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n", 463 dai->id + 1, dir_name); 464 return err; 465 } 466 467 return 0; 468 } 469 470 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd, 471 struct snd_soc_dai *dai) 472 { 473 int err; 474 475 err = snd_dmaengine_pcm_trigger(substream, cmd); 476 if (err) 477 return err; 478 479 switch (cmd) { 480 case SNDRV_PCM_TRIGGER_START: 481 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 482 case SNDRV_PCM_TRIGGER_RESUME: 483 return tegra_admaif_start(dai, substream->stream); 484 case SNDRV_PCM_TRIGGER_STOP: 485 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 486 case SNDRV_PCM_TRIGGER_SUSPEND: 487 return tegra_admaif_stop(dai, substream->stream); 488 default: 489 return -EINVAL; 490 } 491 } 492 493 static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, 494 struct snd_ctl_elem_value *ucontrol) 495 { 496 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 497 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 498 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 499 500 ucontrol->value.enumerated.item[0] = 501 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; 502 503 return 0; 504 } 505 506 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, 507 struct snd_ctl_elem_value *ucontrol) 508 { 509 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 510 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 511 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 512 unsigned int value = ucontrol->value.enumerated.item[0]; 513 514 if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]) 515 return 0; 516 517 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; 518 519 return 1; 520 } 521 522 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, 523 struct snd_ctl_elem_value *ucontrol) 524 { 525 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 526 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 527 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 528 529 ucontrol->value.enumerated.item[0] = 530 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; 531 532 return 0; 533 } 534 535 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, 536 struct snd_ctl_elem_value *ucontrol) 537 { 538 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 539 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 540 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 541 unsigned int value = ucontrol->value.enumerated.item[0]; 542 543 if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]) 544 return 0; 545 546 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; 547 548 return 1; 549 } 550 551 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, 552 struct snd_ctl_elem_value *ucontrol) 553 { 554 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 555 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 556 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 557 558 ucontrol->value.enumerated.item[0] = 559 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; 560 561 return 0; 562 } 563 564 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, 565 struct snd_ctl_elem_value *ucontrol) 566 { 567 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 568 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 569 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 570 unsigned int value = ucontrol->value.enumerated.item[0]; 571 572 if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]) 573 return 0; 574 575 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; 576 577 return 1; 578 } 579 580 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, 581 struct snd_ctl_elem_value *ucontrol) 582 { 583 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 584 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 585 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 586 587 ucontrol->value.enumerated.item[0] = 588 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; 589 590 return 0; 591 } 592 593 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, 594 struct snd_ctl_elem_value *ucontrol) 595 { 596 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 597 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 598 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 599 unsigned int value = ucontrol->value.enumerated.item[0]; 600 601 if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]) 602 return 0; 603 604 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; 605 606 return 1; 607 } 608 609 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) 610 { 611 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); 612 613 snd_soc_dai_init_dma_data(dai, &admaif->playback_dma_data[dai->id], 614 &admaif->capture_dma_data[dai->id]); 615 616 return 0; 617 } 618 619 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { 620 .probe = tegra_admaif_dai_probe, 621 .hw_params = tegra_admaif_hw_params, 622 .trigger = tegra_admaif_trigger, 623 .shutdown = tegra_admaif_shutdown, 624 .prepare = tegra_admaif_prepare, 625 }; 626 627 #define DAI(dai_name, channel) \ 628 { \ 629 .name = dai_name, \ 630 .playback = { \ 631 .stream_name = dai_name " Playback", \ 632 .channels_min = 1, \ 633 .channels_max = channel, \ 634 .rates = SNDRV_PCM_RATE_8000_192000, \ 635 .formats = SNDRV_PCM_FMTBIT_S8 | \ 636 SNDRV_PCM_FMTBIT_S16_LE | \ 637 SNDRV_PCM_FMTBIT_S24_LE | \ 638 SNDRV_PCM_FMTBIT_S32_LE, \ 639 }, \ 640 .capture = { \ 641 .stream_name = dai_name " Capture", \ 642 .channels_min = 1, \ 643 .channels_max = channel, \ 644 .rates = SNDRV_PCM_RATE_8000_192000, \ 645 .formats = SNDRV_PCM_FMTBIT_S8 | \ 646 SNDRV_PCM_FMTBIT_S16_LE | \ 647 SNDRV_PCM_FMTBIT_S24_LE | \ 648 SNDRV_PCM_FMTBIT_S32_LE, \ 649 }, \ 650 .ops = &tegra_admaif_dai_ops, \ 651 } 652 653 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = { 654 DAI("ADMAIF1", TEGRA210_ADMAIF_MAX_CHANNEL), 655 DAI("ADMAIF2", TEGRA210_ADMAIF_MAX_CHANNEL), 656 DAI("ADMAIF3", TEGRA210_ADMAIF_MAX_CHANNEL), 657 DAI("ADMAIF4", TEGRA210_ADMAIF_MAX_CHANNEL), 658 DAI("ADMAIF5", TEGRA210_ADMAIF_MAX_CHANNEL), 659 DAI("ADMAIF6", TEGRA210_ADMAIF_MAX_CHANNEL), 660 DAI("ADMAIF7", TEGRA210_ADMAIF_MAX_CHANNEL), 661 DAI("ADMAIF8", TEGRA210_ADMAIF_MAX_CHANNEL), 662 DAI("ADMAIF9", TEGRA210_ADMAIF_MAX_CHANNEL), 663 DAI("ADMAIF10", TEGRA210_ADMAIF_MAX_CHANNEL), 664 }; 665 666 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = { 667 DAI("ADMAIF1", TEGRA186_ADMAIF_MAX_CHANNEL), 668 DAI("ADMAIF2", TEGRA186_ADMAIF_MAX_CHANNEL), 669 DAI("ADMAIF3", TEGRA186_ADMAIF_MAX_CHANNEL), 670 DAI("ADMAIF4", TEGRA186_ADMAIF_MAX_CHANNEL), 671 DAI("ADMAIF5", TEGRA186_ADMAIF_MAX_CHANNEL), 672 DAI("ADMAIF6", TEGRA186_ADMAIF_MAX_CHANNEL), 673 DAI("ADMAIF7", TEGRA186_ADMAIF_MAX_CHANNEL), 674 DAI("ADMAIF8", TEGRA186_ADMAIF_MAX_CHANNEL), 675 DAI("ADMAIF9", TEGRA186_ADMAIF_MAX_CHANNEL), 676 DAI("ADMAIF10", TEGRA186_ADMAIF_MAX_CHANNEL), 677 DAI("ADMAIF11", TEGRA186_ADMAIF_MAX_CHANNEL), 678 DAI("ADMAIF12", TEGRA186_ADMAIF_MAX_CHANNEL), 679 DAI("ADMAIF13", TEGRA186_ADMAIF_MAX_CHANNEL), 680 DAI("ADMAIF14", TEGRA186_ADMAIF_MAX_CHANNEL), 681 DAI("ADMAIF15", TEGRA186_ADMAIF_MAX_CHANNEL), 682 DAI("ADMAIF16", TEGRA186_ADMAIF_MAX_CHANNEL), 683 DAI("ADMAIF17", TEGRA186_ADMAIF_MAX_CHANNEL), 684 DAI("ADMAIF18", TEGRA186_ADMAIF_MAX_CHANNEL), 685 DAI("ADMAIF19", TEGRA186_ADMAIF_MAX_CHANNEL), 686 DAI("ADMAIF20", TEGRA186_ADMAIF_MAX_CHANNEL), 687 }; 688 689 static struct snd_soc_dai_driver tegra264_admaif_cmpnt_dais[] = { 690 DAI("ADMAIF1", TEGRA264_ADMAIF_MAX_CHANNEL), 691 DAI("ADMAIF2", TEGRA264_ADMAIF_MAX_CHANNEL), 692 DAI("ADMAIF3", TEGRA264_ADMAIF_MAX_CHANNEL), 693 DAI("ADMAIF4", TEGRA264_ADMAIF_MAX_CHANNEL), 694 DAI("ADMAIF5", TEGRA264_ADMAIF_MAX_CHANNEL), 695 DAI("ADMAIF6", TEGRA264_ADMAIF_MAX_CHANNEL), 696 DAI("ADMAIF7", TEGRA264_ADMAIF_MAX_CHANNEL), 697 DAI("ADMAIF8", TEGRA264_ADMAIF_MAX_CHANNEL), 698 DAI("ADMAIF9", TEGRA264_ADMAIF_MAX_CHANNEL), 699 DAI("ADMAIF10", TEGRA264_ADMAIF_MAX_CHANNEL), 700 DAI("ADMAIF11", TEGRA264_ADMAIF_MAX_CHANNEL), 701 DAI("ADMAIF12", TEGRA264_ADMAIF_MAX_CHANNEL), 702 DAI("ADMAIF13", TEGRA264_ADMAIF_MAX_CHANNEL), 703 DAI("ADMAIF14", TEGRA264_ADMAIF_MAX_CHANNEL), 704 DAI("ADMAIF15", TEGRA264_ADMAIF_MAX_CHANNEL), 705 DAI("ADMAIF16", TEGRA264_ADMAIF_MAX_CHANNEL), 706 DAI("ADMAIF17", TEGRA264_ADMAIF_MAX_CHANNEL), 707 DAI("ADMAIF18", TEGRA264_ADMAIF_MAX_CHANNEL), 708 DAI("ADMAIF19", TEGRA264_ADMAIF_MAX_CHANNEL), 709 DAI("ADMAIF20", TEGRA264_ADMAIF_MAX_CHANNEL), 710 DAI("ADMAIF21", TEGRA264_ADMAIF_MAX_CHANNEL), 711 DAI("ADMAIF22", TEGRA264_ADMAIF_MAX_CHANNEL), 712 DAI("ADMAIF23", TEGRA264_ADMAIF_MAX_CHANNEL), 713 DAI("ADMAIF24", TEGRA264_ADMAIF_MAX_CHANNEL), 714 DAI("ADMAIF25", TEGRA264_ADMAIF_MAX_CHANNEL), 715 DAI("ADMAIF26", TEGRA264_ADMAIF_MAX_CHANNEL), 716 DAI("ADMAIF27", TEGRA264_ADMAIF_MAX_CHANNEL), 717 DAI("ADMAIF28", TEGRA264_ADMAIF_MAX_CHANNEL), 718 DAI("ADMAIF29", TEGRA264_ADMAIF_MAX_CHANNEL), 719 DAI("ADMAIF30", TEGRA264_ADMAIF_MAX_CHANNEL), 720 DAI("ADMAIF31", TEGRA264_ADMAIF_MAX_CHANNEL), 721 DAI("ADMAIF32", TEGRA264_ADMAIF_MAX_CHANNEL), 722 }; 723 724 static const char * const tegra_admaif_stereo_conv_text[] = { 725 "CH0", "CH1", "AVG", 726 }; 727 728 static const char * const tegra_admaif_mono_conv_text[] = { 729 "Zero", "Copy", 730 }; 731 732 /* 733 * Below macro is added to avoid looping over all ADMAIFx controls related 734 * to mono/stereo conversions in get()/put() callbacks. 735 */ 736 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text) \ 737 { \ 738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 739 .info = snd_soc_info_enum_double, \ 740 .name = xname, \ 741 .get = xhandler_get, \ 742 .put = xhandler_put, \ 743 .private_value = (unsigned long)&(struct soc_enum) \ 744 SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text) \ 745 } 746 747 #define TEGRA_ADMAIF_CIF_CTRL(reg) \ 748 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \ 749 tegra210_admaif_pget_mono_to_stereo, \ 750 tegra210_admaif_pput_mono_to_stereo, \ 751 tegra_admaif_mono_conv_text), \ 752 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \ 753 tegra210_admaif_pget_stereo_to_mono, \ 754 tegra210_admaif_pput_stereo_to_mono, \ 755 tegra_admaif_stereo_conv_text), \ 756 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ 757 tegra210_admaif_cget_mono_to_stereo, \ 758 tegra210_admaif_cput_mono_to_stereo, \ 759 tegra_admaif_mono_conv_text), \ 760 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ 761 tegra210_admaif_cget_stereo_to_mono, \ 762 tegra210_admaif_cput_stereo_to_mono, \ 763 tegra_admaif_stereo_conv_text) 764 765 static struct snd_kcontrol_new tegra210_admaif_controls[] = { 766 TEGRA_ADMAIF_CIF_CTRL(1), 767 TEGRA_ADMAIF_CIF_CTRL(2), 768 TEGRA_ADMAIF_CIF_CTRL(3), 769 TEGRA_ADMAIF_CIF_CTRL(4), 770 TEGRA_ADMAIF_CIF_CTRL(5), 771 TEGRA_ADMAIF_CIF_CTRL(6), 772 TEGRA_ADMAIF_CIF_CTRL(7), 773 TEGRA_ADMAIF_CIF_CTRL(8), 774 TEGRA_ADMAIF_CIF_CTRL(9), 775 TEGRA_ADMAIF_CIF_CTRL(10), 776 }; 777 778 static struct snd_kcontrol_new tegra186_admaif_controls[] = { 779 TEGRA_ADMAIF_CIF_CTRL(1), 780 TEGRA_ADMAIF_CIF_CTRL(2), 781 TEGRA_ADMAIF_CIF_CTRL(3), 782 TEGRA_ADMAIF_CIF_CTRL(4), 783 TEGRA_ADMAIF_CIF_CTRL(5), 784 TEGRA_ADMAIF_CIF_CTRL(6), 785 TEGRA_ADMAIF_CIF_CTRL(7), 786 TEGRA_ADMAIF_CIF_CTRL(8), 787 TEGRA_ADMAIF_CIF_CTRL(9), 788 TEGRA_ADMAIF_CIF_CTRL(10), 789 TEGRA_ADMAIF_CIF_CTRL(11), 790 TEGRA_ADMAIF_CIF_CTRL(12), 791 TEGRA_ADMAIF_CIF_CTRL(13), 792 TEGRA_ADMAIF_CIF_CTRL(14), 793 TEGRA_ADMAIF_CIF_CTRL(15), 794 TEGRA_ADMAIF_CIF_CTRL(16), 795 TEGRA_ADMAIF_CIF_CTRL(17), 796 TEGRA_ADMAIF_CIF_CTRL(18), 797 TEGRA_ADMAIF_CIF_CTRL(19), 798 TEGRA_ADMAIF_CIF_CTRL(20), 799 }; 800 801 static struct snd_kcontrol_new tegra264_admaif_controls[] = { 802 TEGRA_ADMAIF_CIF_CTRL(1), 803 TEGRA_ADMAIF_CIF_CTRL(2), 804 TEGRA_ADMAIF_CIF_CTRL(3), 805 TEGRA_ADMAIF_CIF_CTRL(4), 806 TEGRA_ADMAIF_CIF_CTRL(5), 807 TEGRA_ADMAIF_CIF_CTRL(6), 808 TEGRA_ADMAIF_CIF_CTRL(7), 809 TEGRA_ADMAIF_CIF_CTRL(8), 810 TEGRA_ADMAIF_CIF_CTRL(9), 811 TEGRA_ADMAIF_CIF_CTRL(10), 812 TEGRA_ADMAIF_CIF_CTRL(11), 813 TEGRA_ADMAIF_CIF_CTRL(12), 814 TEGRA_ADMAIF_CIF_CTRL(13), 815 TEGRA_ADMAIF_CIF_CTRL(14), 816 TEGRA_ADMAIF_CIF_CTRL(15), 817 TEGRA_ADMAIF_CIF_CTRL(16), 818 TEGRA_ADMAIF_CIF_CTRL(17), 819 TEGRA_ADMAIF_CIF_CTRL(18), 820 TEGRA_ADMAIF_CIF_CTRL(19), 821 TEGRA_ADMAIF_CIF_CTRL(20), 822 TEGRA_ADMAIF_CIF_CTRL(21), 823 TEGRA_ADMAIF_CIF_CTRL(22), 824 TEGRA_ADMAIF_CIF_CTRL(23), 825 TEGRA_ADMAIF_CIF_CTRL(24), 826 TEGRA_ADMAIF_CIF_CTRL(25), 827 TEGRA_ADMAIF_CIF_CTRL(26), 828 TEGRA_ADMAIF_CIF_CTRL(27), 829 TEGRA_ADMAIF_CIF_CTRL(28), 830 TEGRA_ADMAIF_CIF_CTRL(29), 831 TEGRA_ADMAIF_CIF_CTRL(30), 832 TEGRA_ADMAIF_CIF_CTRL(31), 833 TEGRA_ADMAIF_CIF_CTRL(32), 834 }; 835 836 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = { 837 .controls = tegra210_admaif_controls, 838 .num_controls = ARRAY_SIZE(tegra210_admaif_controls), 839 .pcm_construct = tegra_pcm_construct, 840 .open = tegra_pcm_open, 841 .close = tegra_pcm_close, 842 .hw_params = tegra_pcm_hw_params, 843 .pointer = tegra_pcm_pointer, 844 }; 845 846 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = { 847 .controls = tegra186_admaif_controls, 848 .num_controls = ARRAY_SIZE(tegra186_admaif_controls), 849 .pcm_construct = tegra_pcm_construct, 850 .open = tegra_pcm_open, 851 .close = tegra_pcm_close, 852 .hw_params = tegra_pcm_hw_params, 853 .pointer = tegra_pcm_pointer, 854 }; 855 856 static const struct snd_soc_component_driver tegra264_admaif_cmpnt = { 857 .controls = tegra264_admaif_controls, 858 .num_controls = ARRAY_SIZE(tegra264_admaif_controls), 859 .pcm_construct = tegra_pcm_construct, 860 .open = tegra_pcm_open, 861 .close = tegra_pcm_close, 862 .hw_params = tegra_pcm_hw_params, 863 .pointer = tegra_pcm_pointer, 864 }; 865 866 static const struct tegra_admaif_soc_data soc_data_tegra210 = { 867 .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT, 868 .max_stream_ch = TEGRA210_ADMAIF_MAX_CHANNEL, 869 .cmpnt = &tegra210_admaif_cmpnt, 870 .dais = tegra210_admaif_cmpnt_dais, 871 .regmap_conf = &tegra210_admaif_regmap_config, 872 .global_base = TEGRA210_ADMAIF_GLOBAL_BASE, 873 .tx_base = TEGRA210_ADMAIF_TX_BASE, 874 .rx_base = TEGRA210_ADMAIF_RX_BASE, 875 }; 876 877 static const struct tegra_admaif_soc_data soc_data_tegra186 = { 878 .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT, 879 .max_stream_ch = TEGRA186_ADMAIF_MAX_CHANNEL, 880 .cmpnt = &tegra186_admaif_cmpnt, 881 .dais = tegra186_admaif_cmpnt_dais, 882 .regmap_conf = &tegra186_admaif_regmap_config, 883 .global_base = TEGRA186_ADMAIF_GLOBAL_BASE, 884 .tx_base = TEGRA186_ADMAIF_TX_BASE, 885 .rx_base = TEGRA186_ADMAIF_RX_BASE, 886 }; 887 888 static const struct tegra_admaif_soc_data soc_data_tegra264 = { 889 .num_ch = TEGRA264_ADMAIF_CHANNEL_COUNT, 890 .max_stream_ch = TEGRA264_ADMAIF_MAX_CHANNEL, 891 .cmpnt = &tegra264_admaif_cmpnt, 892 .dais = tegra264_admaif_cmpnt_dais, 893 .regmap_conf = &tegra264_admaif_regmap_config, 894 .global_base = TEGRA264_ADMAIF_GLOBAL_BASE, 895 .tx_base = TEGRA264_ADMAIF_TX_BASE, 896 .rx_base = TEGRA264_ADMAIF_RX_BASE, 897 }; 898 899 static const struct of_device_id tegra_admaif_of_match[] = { 900 { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 }, 901 { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 }, 902 { .compatible = "nvidia,tegra264-admaif", .data = &soc_data_tegra264 }, 903 {}, 904 }; 905 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match); 906 907 static int tegra_admaif_probe(struct platform_device *pdev) 908 { 909 struct tegra_admaif *admaif; 910 void __iomem *regs; 911 struct resource *res; 912 int err, i; 913 914 admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL); 915 if (!admaif) 916 return -ENOMEM; 917 918 admaif->soc_data = of_device_get_match_data(&pdev->dev); 919 920 dev_set_drvdata(&pdev->dev, admaif); 921 922 admaif->capture_dma_data = 923 devm_kcalloc(&pdev->dev, 924 admaif->soc_data->num_ch, 925 sizeof(struct snd_dmaengine_dai_dma_data), 926 GFP_KERNEL); 927 if (!admaif->capture_dma_data) 928 return -ENOMEM; 929 930 admaif->playback_dma_data = 931 devm_kcalloc(&pdev->dev, 932 admaif->soc_data->num_ch, 933 sizeof(struct snd_dmaengine_dai_dma_data), 934 GFP_KERNEL); 935 if (!admaif->playback_dma_data) 936 return -ENOMEM; 937 938 for (i = 0; i < ADMAIF_PATHS; i++) { 939 admaif->mono_to_stereo[i] = 940 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch, 941 sizeof(unsigned int), GFP_KERNEL); 942 if (!admaif->mono_to_stereo[i]) 943 return -ENOMEM; 944 945 admaif->stereo_to_mono[i] = 946 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch, 947 sizeof(unsigned int), GFP_KERNEL); 948 if (!admaif->stereo_to_mono[i]) 949 return -ENOMEM; 950 } 951 952 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 953 if (IS_ERR(regs)) 954 return PTR_ERR(regs); 955 956 admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 957 admaif->soc_data->regmap_conf); 958 if (IS_ERR(admaif->regmap)) { 959 dev_err(&pdev->dev, "regmap init failed\n"); 960 return PTR_ERR(admaif->regmap); 961 } 962 963 regcache_cache_only(admaif->regmap, true); 964 965 err = tegra_isomgr_adma_register(&pdev->dev); 966 if (err) { 967 dev_err(&pdev->dev, "Failed to add interconnect path\n"); 968 return err; 969 } 970 971 regmap_update_bits(admaif->regmap, admaif->soc_data->global_base + 972 TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1); 973 974 for (i = 0; i < admaif->soc_data->num_ch; i++) { 975 admaif->playback_dma_data[i].addr = res->start + 976 CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i); 977 978 admaif->capture_dma_data[i].addr = res->start + 979 CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i); 980 981 admaif->playback_dma_data[i].addr_width = 32; 982 983 if (of_property_read_string_index(pdev->dev.of_node, 984 "dma-names", (i * 2) + 1, 985 &admaif->playback_dma_data[i].chan_name) < 0) { 986 dev_err(&pdev->dev, 987 "missing property nvidia,dma-names\n"); 988 989 return -ENODEV; 990 } 991 992 admaif->capture_dma_data[i].addr_width = 32; 993 994 if (of_property_read_string_index(pdev->dev.of_node, 995 "dma-names", 996 (i * 2), 997 &admaif->capture_dma_data[i].chan_name) < 0) { 998 dev_err(&pdev->dev, 999 "missing property nvidia,dma-names\n"); 1000 1001 return -ENODEV; 1002 } 1003 } 1004 1005 err = devm_snd_soc_register_component(&pdev->dev, 1006 admaif->soc_data->cmpnt, 1007 admaif->soc_data->dais, 1008 admaif->soc_data->num_ch); 1009 if (err) { 1010 dev_err(&pdev->dev, 1011 "can't register ADMAIF component, err: %d\n", err); 1012 return err; 1013 } 1014 1015 pm_runtime_enable(&pdev->dev); 1016 1017 return 0; 1018 } 1019 1020 static void tegra_admaif_remove(struct platform_device *pdev) 1021 { 1022 tegra_isomgr_adma_unregister(&pdev->dev); 1023 pm_runtime_disable(&pdev->dev); 1024 } 1025 1026 static const struct dev_pm_ops tegra_admaif_pm_ops = { 1027 RUNTIME_PM_OPS(tegra_admaif_runtime_suspend, 1028 tegra_admaif_runtime_resume, NULL) 1029 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) 1030 }; 1031 1032 static struct platform_driver tegra_admaif_driver = { 1033 .probe = tegra_admaif_probe, 1034 .remove = tegra_admaif_remove, 1035 .driver = { 1036 .name = "tegra210-admaif", 1037 .of_match_table = tegra_admaif_of_match, 1038 .pm = pm_ptr(&tegra_admaif_pm_ops), 1039 }, 1040 }; 1041 module_platform_driver(tegra_admaif_driver); 1042 1043 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>"); 1044 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver"); 1045 MODULE_LICENSE("GPL v2"); 1046