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